1. 程式人生 > >spring中AOP的兩種實現方式

spring中AOP的兩種實現方式

1.方法一:註解實現

介面類

public interface User {
       public void work();
}

具體實現類

public class IUser implements User {

	public void work() {
	     System.out.println("-------工作ing----------");
	}

}

切面類

public void doBefore() {
		 System.out.println("-------1.執行前通知--------");
	}
	public void doAfterReturning() {
		 System.out.println("-------2.執行無異常後通知--------");
	}
	public Object Around(ProceedingJoinPoint p) throws Throwable {
		 System.out.println("----------3.環繞通知前-------");
		 Object proceed = p.proceed();
		 System.out.println("----------3.環繞通知後--");
		return p;
	}
	public void AfterThrowing() {
		System.out.println("--------4.執行後出現異常通知+-----");
	}
	
	public void After() {
		System.out.println("-------5.執行方法後無論是否出現異常均執行----finally");
	}

注意執行環繞通知時 使用 ProceedingJoinPoint 獲取執行的方法資訊

配置檔案

    <!-- 宣告一個業務類既代理的物件 -->
     <bean id="IUser"  class="AOP2.IUser"> </bean>
     <!-- 宣告一個通知類既切面 -->
     <bean id="MyProxy"  class="AOP2.MyProxy"></bean>
     
     <aop:config>
              <!--宣告具體通知類的配置  -->
              <aop:aspect ref="MyProxy">
                     <aop:pointcut expression="execution(* AOP2.IUser.*(..))" id="pointcut"/>
                     
                     <aop:before method="doBefore" pointcut-ref="pointcut"/>
                      <aop:after method="After" pointcut-ref="pointcut"/>
                      <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut"  returning="result"/>
                      <aop:after-throwing method="AfterThrowing" pointcut-ref="pointcut"  throwing="ex"/>
                      <aop:around method="Around"  pointcut-ref="pointcut"/>
              </aop:aspect>
     </aop:config>

測試類

 ClassPathXmlApplicationContext context = new  ClassPathXmlApplicationContext("spring.xml");
		 User user = (User) context.getBean("IUser"); //注意宣告的類為介面 
        user.work();//以JDK代理實現AOP功能

方法二:註解實現

切面類

  @Pointcut("execution(* AOP.IUser.*(..))")
      public void pointCut() {
    	  
      }
      @Before("pointCut()")
      public void doBefore() {
    	  System.out.println("-------1執行前通知--------");
      }
      @AfterReturning("pointCut()")
      public void doAfter() {
    	  System.out.println("-------2執行無異常後通知--------");
      }
      @After("pointCut()")
      public void doEnd() {
    	  System.out.println("---------3執行後最終通知--不管是否發生異常都執行-----");
      }
      @Around("pointCut()")
      public Object doAround(ProceedingJoinPoint p) throws Throwable {
    	  System.out.println("----------5.環繞通知開始---------");
    	  Object proceed = p.proceed();
    	  System.out.println("----------5.環繞通知結束----------");
		return p;
      }
      @AfterThrowing("pointCut()")
      public void doError() {
    	  System.out.println("------------4執行異常通知----------");
      }

注意使用@PointCut宣告切點

測試類

		 ClassPathXmlApplicationContext context = new  ClassPathXmlApplicationContext("spring.xml");
		 IUser user = (IUser) context.getBean("IUser");
        user.work();

注意:

  1. Target 目標物件既具體的業務類
  2. proxy 代理物件既 通知類或切面類
  3. pointcut 切點 業務類中某個方法進行攔截的方法
  4. jionpoint 連線點 業務類中所有方法
  5. 宣告切點的方法可以為 execution(* AOP.IUser.*(..))      
  6.  execution()表明主題類  
  7. 第一個* 表示返回型別任意
  8. 包名
  9. 第一個. 代表此包 第二個.為此包下的所有子包 (這裡沒有寫第二個.)
  10. *(..)代表所有類中所有方法
  11. (..)類中所有方法