Spring實現AOP2

  • Spring框架一般都是基於AspectJ實現AOP操作

    • AspectJ不是Spring組成部分,獨立AOP框架,一般吧AspectJ和Spring框架一起使用,進行AOP操作
  • 基於AspectJ實現AOP操作

    • 基於xml配置文件實現
    • 基於註解方式實現(使用)
  • 在項目中引入AOP依賴

    • 使用maven
  • 切入點表達式

    • 切入點表達式作用:知道對哪個類型裏面的哪個方法進行增強
    • 語法結構:execution(【權限修飾符】【返回類型】【類全路徑】【參數列表】)

    舉例1:對com.qi.dao.BookDao類裏面的add進行增強

    execution(* com.qi.dao.BookDao.add(…))

    舉例2:對com.qi.dao.BookDao類裏面的所有方法進行增強

    execution(* com.qi.dao.BookDao.*(…))

    舉例3:對com.qi.dao包裏面的所有類,類中的所有方法進行增強

    execution(* com.qi.dao.* .*(…))

AOP操作(AspectJ註解)

  • 創建一個類,在類中定義方法

    public class User {
        public void add(){
            System.out.println("執行add方法。。。。。");
        }
    }
    
  • 創建增強類(編寫增強邏輯)

    public class UserProxy {
        public void before(){
            System.out.println("在add方法之前執行。。。");
        }
    }
    
  • 進行通知的配置

    • 在Spring配置文件中,開啓註解掃描

      <!--    開啓註解掃描-->
          <context:component-scan base-package="com.qi.annoAOP"></context:component-scan>
      
    • 使用註解創建User和UserProxy對象

      @Component
      public class User {
          public void add(){
              System.out.println("執行add方法。。。。。");
          }
      }
      
      @Component
      public class UserProxy {
          //前置通知
          public void before(){
              System.out.println("在add方法之前執行。。。");
          }
      }
      
    • 在增強類上面添加註解@AspectJ

      @Component
      @Aspect //生產代理對象
      public class UserProxy {
          //前置通知
          public void before(){
              System.out.println("在add方法之前執行。。。");
          }
      }
      
    • 在Spring配置文件中開啓生產代理對象

      <!--    開啓AspectJ 生成代理對象-->
      <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
      
  • 配置不同的類型通知

    • 在增強類的裏面,在作爲通知方法上面添加通知類型的註解,使用切入點表達式配置
    //增強的類
    @Component
    @Aspect //生產代理對象
    public class UserProxy {
    
        //前置通知
        // 使用Before註解表示作爲前置通知
        @Before("execution(* com.qi.annoAOP.User.add(..))")
        public void before(){
            System.out.println("前置Before通知。。。");
        }
        //最終通知
        @After("execution(* com.qi.annoAOP.User.add(..))")
        public void after(){
            System.out.println("後置After通知。。。");
        }
    
        //後置通知,在程序有返回值的時候執行
        @AfterReturning("execution(* com.qi.annoAOP.User.add(..))")
        public void afterReturning(){
            System.out.println("afterReturning通知。。。");
        }
    
        //出現異常才執行
        @AfterThrowing("execution(* com.qi.annoAOP.User.add(..))")
        public void afterThrowing(){
            System.out.println("AfterThrowing通知。。。");
        }
    
        //環繞通知
        @Around("execution(* com.qi.annoAOP.User.add(..))")
        public void around(ProceedingJoinPoint proceedingJoinPoint){
            System.out.println("環繞之前。。。");
    
            try {
                proceedingJoinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            System.out.println("環繞之後。。。");
        }
    }
    
  • 公共切入點的提取
    在這裏插入圖片描述

@Component
@Aspect //生產代理對象
public class UserProxy {
    @Pointcut("execution(* com.qi.annoAOP.User.add(..))")
    public void pointDemo(){

    }
    //前置通知
    // 使用Before註解表示作爲前置通知
    @Before("pointDemo()")
    public void before(){
        System.out.println("前置Before通知。。。");
    }
    
}
  • 有多個增強類對同一方法進行增強,設置增強類優先級

    • 在增強類上面增加註解@Order(數字值),數字值越小,優先級越高
    @Component
    @Aspect
    @Order(1)
    public class PersonProxy {
        //前置通知
    
        @Before("execution(* com.qi.annoAOP.User.add())")
        public void befor(){
            System.out.println("Person的前置通知");
        }
    }
    
  • 完全使用註解開發

    @Configuration
    @ComponentScan(basePackages = {"com.qi"})
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    public class ConfigAOP {
        
    }
    

AOP操作(AspectJ配置文件)

<!--                                 使用配置文件                            -->
<!--    創建對象-->
    <bean id="book" class="com.qi.xmlAOP.Book"></bean>
    <bean id="bookProxy" class="com.qi.xmlAOP.BookProxy"></bean>

<!--    配置AOP增強-->
    <aop:config>
<!--        切入點-->
        <aop:pointcut id="pointcut" expression="execution(* com.qi.xmlAOP.Book.buy(..))"/>
<!--        切面-->
        <aop:aspect ref="bookProxy">
<!--            增強作用在具體方法上-->
            <aop:before method="before" pointcut-ref="pointcut"></aop:before>
        </aop:aspect>
    </aop:config>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章