SpringBoot

SpringBoot AOP

2018-08-14  本文已影响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();

    }
}
上一篇下一篇

猜你喜欢

热点阅读