程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> AOP面向切面編程的四種實現,aop面向切面四種

AOP面向切面編程的四種實現,aop面向切面四種

編輯:JAVA綜合教程

AOP面向切面編程的四種實現,aop面向切面四種


          一.AOP(面向切面編程)的四種實現分別為最原始的經典AOP、代理工廠bean(ProxyFacteryBean)和默認自動代理DefaultAdvisorAutoProxyCreator以及BeanNameAutoProxyCreator代理、Aspectj的注解和xml配置文件。

     1.代理工廠bean(ProxyFacteryBean)的方式

      1.1 接口(Interface)

 

1 package cn.happy.interfaces;
2 
3 public interface Advice {
4 
5     public void fristMethod();
6     
7     public String secondMethod();
8 }

         1.2  接口的實現類

 1 package cn.happy.impl;
 2 
 3 import cn.happy.interfaces.Advice;
 4 
 5 public class AdviceImpl implements Advice {
 6 
 7     public void fristMethod() {
 8          System.out.println("==fristMethod==");
 9     }
10 
11     public String secondMethod() {
12         System.out.println("==secondMethod==");
13         return "abc";
14     }
15 
16 }

 

 

         1.3 各種通知增強

       1.3.1 前置增強

 1 package cn.happy.advice;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 public class MethodBeforeAdvice implements
 6         org.springframework.aop.MethodBeforeAdvice {
 7 
 8     public void before(Method arg0, Object[] arg1, Object arg2)
 9             throws Throwable {
10         System.out.println("==Before==");
11          
12     }
13 
14 }

 

 

        1.3.2  後置增強

 1 package cn.happy.advice;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.springframework.aop.AfterReturningAdvice;
 6 
 7 public class AfterReturningAdvie implements AfterReturningAdvice {
 8 
 9     public void afterReturning(Object arg0, Method arg1, Object[] arg2,
10             Object arg3) throws Throwable {
11         System.out.println("==After==");
12 
13     }
14 
15 }

 

 

      1.3.3  環繞增強

package cn.happy.aroundadvice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyInterceptor implements MethodInterceptor{

    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("==before==");
        String result= (String)invocation.proceed();
        System.out.println("==after==");
        return result;
    }
}

 

        

      1.3.4 異常增強

package cn.happy.exception;

import org.springframework.aop.ThrowsAdvice;

public class MyException implements ThrowsAdvice {
    public void afterThrowing(Exception ex){
        System.out.println("異常通知");
    }
}

 

        

         1.4 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        
        <!-- 實現類的引入 -->
        <bean id="adviceimpl" class="cn.happy.impl.AdviceImpl"></bean>
       <!-- 前置增強  通知-->
        <bean id="advicebefore" class="cn.happy.advice.MethodBeforeAdvice"></bean>
        <!-- 後置增強  通知-->
        <bean id="adviceafter" class="cn.happy.advice.AfterReturningAdvie"></bean>
        
        <!-- 環繞增強 -->
        <bean id="around" class="cn.happy.aroundadvice.MyInterceptor"></bean>
        
        <!-- 關聯  代理工廠bean ProxyFacteryBean 通知 -->
        <!--<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
           
           <property name="targetName" value="adviceimpl"></property>
           <property name="interceptorNames" value="advicebefore,adviceafter"></property>
           
        </bean>-->
        
        <!-- 環繞增強 代理工廠 顧問包裝通知 -->
        <bean id="aroundserviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
           
           <property name="target" ref="adviceimpl"></property>
           <property name="interceptorNames" value="beforeadvisor"></property>
           
        </bean>
        
        <!-- 切面  通知  -->
        <bean id="beforeadvice" class="cn.happy.mymethodbefore.MyMethodBeforeAdvice"></bean>
        
        <!-- 顧問  包裝advice -->
        <bean id="beforeadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
         <property name="advice" ref="beforeadvice"></property>
         <property name="mappedNames" value="fristMethod,secondMethod"></property>
        </bean>
        
        <!-- 顧問  包裝advice 正則表達式-->
        <!--<bean id="beforeadvisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
         <property name="advice" ref="beforeadvice"></property>
         <property name="pattern" value=".*Method.*"></property>
        </bean>-->
        
        
        <!-- 默認自動代理  默認只找通知-->
        <!--<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>-->
        
        <!-- beanname自動代理 可以選擇顧問或者通知-->
        <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
          <property name="beanNames" value="adviceimpl"></property>
          <property name="interceptorNames" value="beforeadvisor"></property>
        </bean>
        
</beans>

 

  

       1.5 測試類

package cn.happy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.interfaces.Advice;

public class Test {
    /**
     * 通知的前置和後置測試
     */
    public static void main(String[] args) {
        //解析配置文件
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        Advice advice= (Advice)ctx.getBean("adviceimpl"); //自動代理beanname的方式
        advice.fristMethod();
        advice.secondMethod();
    }
}

 

 

       2. 最原始的經典AOP

    2.1 最基本分層模式dao、biz、service以及最後測試Test

    2.1.1DAO層

package cn.happy.dao;

import cn.happy.entity.User;

   //接口
public interface UDao {

    //保存方法
    public void save(User user);
}

 //實現類
package cn.happy.dao;

import cn.happy.entity.User;

public class UserDaoImpl implements UDao{

    public void save(User user) {
        System.out.println("保存成功");
    }

}

 

 

     2.1.2 BIZ層

package cn.happy.biz;

import cn.happy.entity.User;

  //業務接口
public interface UBiz {

    //保存方法
    public void save2(User user);
}

  //業務實現類
package cn.happy.biz;

import cn.happy.dao.UDao;
import cn.happy.entity.User;

public class UserBiz implements UBiz{

    //dao的對象
    private UDao udao;
    public void save2(User user) {
        udao.save(user);
        
    }
    public UDao getUdao() {
        return udao;
    }
    public void setUdao(UDao udao) {
        this.udao = udao;
    }
   
}

 

 

     2.1.3  AOP模塊即service層

 

package cn.happy.logger;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

  //前置內容
public class LoggerBefore implements MethodBeforeAdvice {

    public void before(Method arg0, Object[] arg1, Object arg2)
            throws Throwable {
        System.out.println("save前置內容");   
    }
}


//後置內容
package cn.happy.logger;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class LoggerAfter implements AfterReturningAdvice{

    public void afterReturning(Object arg0, Method arg1, Object[] arg2,
            Object arg3) throws Throwable {
        System.out.println("save後置內容");   
    }
}

 

 

 

 

      2.1.4 經典的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
        <!-- 業務biz與dao接口對象的實現 -->
        <bean id="dao" class="cn.happy.dao.UserDaoImpl"></bean>
        <bean id="biz" class="cn.happy.biz.UserBiz">
            <property name="udao" ref="dao"></property>
        </bean> 
        <!-- 前置與後置內容的配置 -->
        <bean id="before" class="cn.happy.logger.LoggerBefore"></bean>
        <bean id="after" class="cn.happy.logger.LoggerAfter"></bean>
        <!-- aop的配置 -->
        <aop:config>
          <aop:pointcut expression="execution(public void save2(cn.happy.entity.User))" id="pointcut"/>
          <!-- 在切入點處插入增強處理、完成"織入" -->
          <aop:advisor advice-ref="before" pointcut-ref="pointcut"/>
          <aop:advisor advice-ref="after" pointcut-ref="pointcut"/>
        </aop:config>
</beans>       

 

 

     2.1.5  測試類

package cn.happy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.biz.UBiz;
import cn.happy.entity.User;

public class AOPTest {

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        UBiz ubiz=(UBiz)context.getBean("biz");
        User user=new User();
        ubiz.save2(user);
        System.out.println("save~ok");
    }
}

 

 

       3. 然後就是Aspectj的注解以及xml配置文件的兩種方式了。

     3.1 Aspectj注解

     3.1.1 接口和實現類

package cn.happy.impl;
//接口
public interface AspectDao {
      
    public void add();
    public void delete();
}

//實現類
package cn.happy.impl;

public class AspectjIpml implements AspectDao{
    //添加
    public void add() {
        System.out.println("==ADD==");
    }
    //刪除
    public void delete() {
        System.out.println("==DELETE==");   
    }
}

 

      

      3.1.2 注解類Aspect

package cn.happy.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Before;

@org.aspectj.lang.annotation.Aspect
public class Aspect {
    //前置增強
     @Before(value="execution(public * *(..))")
    public void asBefore(){
        System.out.println("這是前置增強");
    }
   //後置增強
     @AfterReturning(value="execution(public * *(..))")
    public void asAfterReturning(){
        System.out.println("這是後置增強");
    }
   //環繞增強
     @Around(value="execution(public * *(..))")
    public void asAround(ProceedingJoinPoint pj){
         System.out.println("這是環繞前置增強");
         try {
            pj.proceed();
        } catch (Throwable e) {
            //抓捕異常
            e.printStackTrace();
        }
        System.out.println("這是環繞後置增強");
    }
   //異常增強
     @AfterThrowing(value="execution(public * *(..))")
    public void asThorws(){
        System.out.println("這是異常增強");
    }
   //最終增強
     @After(value="execution(public * *(..))")
    public void asAfter(){
        System.out.println("這是最終增強");
    }
}

 

 

     3.1.3  注解的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
     xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
   <!-- 目標對象 -->
   <bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>
   <!-- 增強類 -->
   <bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>
   <!-- 掃描整個項目 關聯注解類和實現類 -->
   <aop:aspectj-autoproxy />

</beans>

 

   

     3.1.4   測試類

package cn.happy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.impl.AspectDao;

public class AspectjTest {
    /**
     * 注解測試 */
    public static void main(String[] args) {
        // 解析配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        AspectDao aspect = (AspectDao) ctx.getBean("aspectimpl");
        aspect.add();
        aspect.delete();
    }
}

 

 

      4. Aspectj的XML配置法,其他的基本都一樣只要修改Aspectj增強類和配置文件就行了

     4.1 Aspect增強類只需將那些注解消去即可

package cn.happy.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;

public class Aspect {
    //前置增強
    public void asBefore(){
        System.out.println("這是前置增強");
    }
    //後置增強
    public void asAfterReturning(){
        
        System.out.println("這是後置增強");
    }
  //環繞增強
    public void asAround(ProceedingJoinPoint pj){
        System.out.println("這是環繞前置增強");
        try {
            pj.proceed();
        } catch (Throwable e) {
            //抓捕異常
            e.printStackTrace();
        }
        System.out.println("這是環繞後置增強");
    }
  //異常增強
    public void asThorws(){
        
        System.out.println("這是異常增強");
    }
  //最終增強
    public void asAfter(){
        
        System.out.println("這是最終增強");
    }
}

 

 

      4.2 XML的配置文件會稍微會復雜一點,但大致的還是跟對原始的經典aop實現方式相同

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
     xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
   <!-- 目標對象 -->
   <bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>
   <!-- 增強類 -->
   <bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>
   <!-- Aspectj的XML配置文件 -->
   <aop:config>
    <aop:pointcut expression="execution(public * *(..))" id="pointcut"/>
    <aop:aspect ref="aspectj">
     <aop:before method="asBefore" pointcut-ref="pointcut"/>
     <aop:after-returning method="asAfterReturning" pointcut-ref="pointcut"/>
     <aop:after-returning method="asAround(org.aspectj.lang.ProceedingJoinPoint)" pointcut-ref="pointcut"/>
     </aop:aspect>
   </aop:config>
</beans>

 

      

      好了,這就是AOP(面向切面編程)的四種實現方式了。希望你們看了之後能讓你們對AOP面向切面編程思想有更深的了解。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved