SpringBoot AOP

作者: 上进的小二狗 | 来源:发表于2018-08-14 16:08 被阅读94次

    一、引言

    二、知识点概要

    SpringBoot AOP开发流程

    1、添加 spring-boot-starter-aop,加入依赖,默认就开始了AOP 的支持
    2、写一个 Aspect,封装横切关注点(日志、监控等),需要配置通知和切入点
    3、这个Aspect 需要纳入到spring容器管理,并且需要加入@Aspect

    spring.aop.auto 配置项决定是否启用AOP,默认启用

    默认是使用基于JDK的动态代理来实现AOP
    spring.aop.proxy-target-class=false 或者不配置,表示使用JDK的动态代理
    =true 表示使用了 cglib
    如果配置了false,而类没有接口,则依然使用cglib

    三、AOP小Demo实现

    1、目录结构如下 项目结构
    2、添加依赖
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
     </dependency>
    
    3、创建UserDao 编写个简单的测试方法
    /**
     * @author liyao
     * @createTime 2018/8/14
     * @description
     */
    @Component
    public class UserDao {
        public void add(String username,String password){
            System.out.println("username"+username+",password:"+password);
        }
    }
    
    4、编写切面LogAspect
    /**
     * @author liyao
     * @createTime 2018/8/14
     * @description
     */
    
    @Aspect
    @Component
    public class LogAspect {
        @Before("execution(* com.ly.aop.dao..*.*(..))")
        public void log(){
            System.out.println("method log done");
        }
    }
    
    5、测试结果 控制台打印

    四、AOP配置设置

    1、是否启用动态代理,通过application.properties 配置

    通过查看: AopAutoConfiguration api

    得知配置:

    #spring.aop.auto 配置项决定是否启用AOP,默认启用
    spring.aop.auto = true
    #默认是使用基于JDK的动态代理来实现AOP
    #spring.aop.proxy-target-class=false 或者不配置,表示使用JDK的动态代理
    #=true 表示使用了 cglib
    #如果配置了false,而类没有接口,则依然使用cglib
    spring.aop.proxy-target-class = true
    
    (1) Cglib 动态代理配置
    spring.aop.auto = true
    #如果配置了false,而类没有接口,则依然使用cglib
    spring.aop.proxy-target-class = true
    

    结果如图:


    cglib动态代理
    (2) JDK动态代理配置

    spring.aop.auto = false 则不会启用
    如下图

    未启用

    默认是使用基于JDK的动态代理来实现AOP,如果配置了false,而类没有接口,则依然使用cglib,因为jdk 动态代理是基于接口实现的

    spring.aop.auto = true
    #如果配置了false,而类没有接口,则依然使用cglib
    spring.aop.proxy-target-class = false
    
    结果如下图: 仍然是 cglib 动态代理方式

    如何处理?
    这里添加一个接口即可:

    public interface IUserDao {
        public void add(String username,String password);
    }
    
    @Component
    public class UserDao implements IUserDao {
            public void add(String username,String password){
                System.out.println("username:"+username+",password:"+password);
            }
    }
    
    结果如图: jdk动态代理

    2、获取操作对象信息的一些api

    /**
     * @author liyao
     * @createTime 2018/8/14
     * @description
     */
    
    @Aspect
    @Component
    public class LogAspect {
        @Before("execution(* com.ly.aop.dao..*.*(..))")
        public void log(){
            System.out.println("before method log done");
            //System.out.println("before method log done" + AopContext.currentProxy().getClass());
        }
       /**
         * 获取通知的信息
         * @param point
         */
        @After("execution(* com.ly.aop.dao..*.*(..))")
        public void logAfter(JoinPoint point){
            System.out.println("after method log done");
            System.out.println(
                     " 操作的对象:"+point.getTarget().getClass()+"args"
                    + " 方法参数:"+Arrays.asList(point.getArgs())
                    + " 方法名:"+point.getSignature().getName());
        }
    }
    
    结果如图: aop

    3、注解配置

    @EnableAspectJAutoProxy 注解有两个属性 属性

    exproxy true ---> 可以 AopContext.currentProxy().getClass()获取代理对象
    exproxy false ---> 不可以获取代理对象

    @EnableAspectJAutoProxy(exposeProxy = true)
    @SpringBootApplication
    public class AopApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(AopApplication.class, args);
            System.out.println(context.getBean(IUserDao.class).getClass());
            context.getBean(IUserDao.class).add("admin","123");
            context.close();
    
        }
    }
    

    相关文章

      网友评论

        本文标题:SpringBoot AOP

        本文链接:https://www.haomeiwen.com/subject/lcdmbftx.html