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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章