AOP_anno 注解方式aop

AOP_anno 注解方式aop

利用注解完成aop配置,首先要完成注解ioc注册Bean,然后再通知类中配置切面和各种通知类型,在给各个方法加上通知类型的注解后,需要设置切入点,利用@Pointcut注解即可设置切入点,再让通知注解引用它。注解aop就完成了。

前期准备

  • 首先pom导包:一个是spring核心包,另一个是用于解析切入点表达式和aop相关的包。

    
        
            org.springframework
            spring-context
            5.2.2.RELEASE
        
    
        
            org.aspectj
            aspectjweaver
            1.9.5
        
    
    
    
  • bean.xml修改为aop和context空间, 因为除了aop还要 ioc注解功能。

    
    
    
    

配置

  • 首先利用注解把业务层和通知层注册为Bean,和原来利用Bean标签效果一样

    @Service("accountService")
    public class AccountService implements IAccountService{...}
        
        //=====
        
    @Component("logger")//表示该类是Bean
    public class Logger{...}
    
  • 配置bean.xml里扫描包,使注解生效

    
    
  • 开启aop服务

    
    
    
  • 配置通知层为切面类

    @Component("logger")//表示该类是Bean
    @Aspect//表示当前类是个切面类
    public class Logger{...}
    
  • 为通知类的各个方法加上通知类型注解,表示对应的通知类型

    @Before()
     public void logSt(){...}
    
    @AfterReturning()
     public void logEd(){...}
    
     @Around()
     public Object aroundLogger(ProceedingJoinPoint pjp){...}
    
  • 但是切入点pointcut在哪里配置呢?利用@Pointcut注解即可,使用一个方法名作为id,切入点表达式和原来xml中pointcut一样

    @Pointcut("execution(* com.chajiu.service.Impl.*.*(..))")
    public void p1(){};
    
  • 让通知类型的注解使用该切入点,注意需要完整的p1(),不可缺括号

    //完整通知类代码
    
    @Component("logger")//表示该类是Bean
    @Aspect//表示当前类是个切面类
    public class Logger {
    
        @Pointcut("execution(* com.chajiu.service.Impl.*.*(..))")
        public void p1(){};
    
        @Before("p1()")
        public void logSt(){
            System.out.println("开始记录日志");
        }
    
        @AfterReturning("p1()")
        public void logEd(){
            System.out.println("结束记录日志");
        }
    
        @Around("p1()")
        public Object aroundLogger(ProceedingJoinPoint pjp){
            Object rtValue=null;
            try {
                Object[] args=pjp.getArgs();
                System.out.println("环绕日志 前置");
                rtValue=pjp.proceed(args);
                System.out.println("环绕日志 后置");
                return rtValue;
            } catch (Throwable throwable) {
                System.out.println("环绕日志 异常");
                throwable.printStackTrace();
            }finally {
                System.out.println("环绕日志 最终");
            }
            return rtValue;
        }
    
    }
    

测试

为了更清晰的看到结果,先注释掉了除了环绕通知外的别的通知。测试类内容和之前的无不同:

public class AOPtest {

    public static void main(String[] args) {
        ApplicationContext ac= new ClassPathXmlApplicationContext("bean.xml");
        IAccountService accountService=(IAccountService) ac.getBean("accountService");
        accountService.saveAccount();
    }
}

结果

E:\jdk\bin\java.exe ...
环绕日志 前置
保存账户了
环绕日志 后置
环绕日志 最终

Process finished with exit code 0

你可能感兴趣的:(AOP_anno 注解方式aop)