【Spring Boot实战与进阶】AOP的两种动态代理(JDK和Cglib)

简介: AOP的两种动态代理(JDK和Cglib)
Spring Boot是很优秀的框架,它的出现简化了新Spring应用的初始搭建以及开发过程,大大减少了代码量,目前已被大多数企业认可和使用。这个专栏将对Spring Boot框架从浅入深,从实战到进阶,不但我们要懂得如何去使用,还要去剖析框架源码,学习其优秀的设计思想。

汇总目录链接:【Spring Boot实战与进阶】学习目录

一、JDK和Cglib两种动态代理方式区别

  1、java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而Cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
  2、JDK动态代理只能对实现了接口的类生成代理,而不能针对类;Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以该类或方法最好不要声明成final 。
  3、Cglib一个目标类方法会生成两个代理方法,一个重写目标方法,并实现代理逻辑,还有一个直接调用目标类方法。

二、AOP的实现原理

想了解原理的可以看这篇【Spring教程】详解AOP的实现原理(动态代理),接下来我们直接通过示例讲如何使用。

1、 引入AOP依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、AOP的配置

2.1 基于Spring的AOP写法

spring.aop.auto=true # 是否启用aop
spring.aop.proxy-target-class=false # 代理方式有接口使用jdk动态代理,如果没有接口使用cglib代理;设置为true时表示强制使用cglib代理

2.2 基于SpringBoot做法 @EnableAopProxyClass

exposeProxy属性表示如果使用true就可以使用AopContext对象获取当前代理对象,false则不能使用
proxyTargetClass true表示使用jdk的动态代理, false表示使用cglib代理

示例一(Cglib动态代理,默认)

1、BookDaoImpl

@Repository
public class BookDaoImpl implements BookDao {

    @Override
    public void addBook(String name, String author) {
        System.out.println("BookDaoImpl实现类:bookName:"+name+", bookAuthor:"+author);
    }
}

2、BookAop

@Component
@Aspect
public class BookAop {
    // 定义切入点
    public static final String POINT_CUT = "execution(* com.example.bootaop.dao..*.*(..))";

    @Before(POINT_CUT)
    public void before() {
        System.out.println("----------添加图书方法前[校验]-----------");
    }

    @After(POINT_CUT)
    public void after(JoinPoint jp) {
        System.out.println("----------添加图书成功后-----------");
        System.out.println(jp.getTarget().getClass());
        System.out.println(Arrays.asList(jp.getArgs()));
    }
}

3、BootAopApplication

@SpringBootApplication
public class BootAopApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext
                context = SpringApplication.run(BootAopApplication.class, args);
        BookDaoImpl bookDao = context.getBean(BookDaoImpl.class);
        System.out.println(bookDao.getClass());
        bookDao.addBook("神雕侠侣", "金庸");
        context.close();
    }
}

控制台输出

class com.example.bootaop.dao.BookDaoImpl$$EnhancerBySpringCGLIB$$2d857802
----------添加图书方法前[校验]-----------
BookDaoImpl实现类:bookName:神雕侠侣, bookAuthor:金庸
----------添加图书成功后-----------
class com.example.bootaop.dao.BookDaoImpl
[神雕侠侣, 金庸]

示例二(JDK动态代理,只能对实现了接口的类生成代理)

1、BookDao

@Repository
public class BookDaoImpl1 implements BookDao {
    @Override
    public void addBook(String name, String author) {

    }
}

2、BookDaoImpl1

@Repository
public class BookDaoImpl1 implements BookDao {
    @Override
    public void addBook(String name, String author) {

    }
}

3、BootAopApplication

@SpringBootApplication
public class BootAopApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext
                context = SpringApplication.run(BootAopApplication.class, args);
        BookDao bookDao = context.getBean("bookDaoImpl1", BookDao.class);//多个实现类时
        System.out.println(bookDao.getClass());
        bookDao.addBook("鹿鼎记", "金庸");
        context.close();
    }
}

配置文件增加:spring.aop.proxy-target-class=false
控制台输出

class com.sun.proxy.$Proxy61
----------添加图书方法前[校验]-----------
----------添加图书成功后-----------
class com.example.bootaop.dao.BookDaoImpl1
[鹿鼎记, 金庸]
相关文章
|
6天前
|
SQL 监控 Java
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
这篇文章介绍了如何在IDEA和Spring Boot中使用AOP技术实现日志信息的记录到数据库的详细步骤和代码示例。
在IDEA 、springboot中使用切面aop实现日志信息的记录到数据库
|
4天前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
2月前
|
Java API
springboot实现aop
springboot实现aop
23 1
|
1月前
|
Java Spring
在Spring Boot中使用AOP实现日志切面
在Spring Boot中使用AOP实现日志切面
|
1天前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
4天前
|
Java Spring 容器
SpringBoot整合AOP实现打印方法执行时间切面
SpringBoot整合AOP实现打印方法执行时间切面
11 1
|
19天前
|
Java API Spring
Spring Boot 中的 AOP 处理
对 Spring Boot 中的切面 AOP 做了详细的讲解,主要介绍了 Spring Boot 中 AOP 的引入,常用注解的使用,参数的使用,以及常用 api 的介绍。AOP 在实际项目中很有用,对切面方法执行前后都可以根据具体的业务,做相应的预处理或者增强处理,同时也可以用作异常捕获处理,可以根据具体业务场景,合理去使用 AOP。
|
4天前
|
Dubbo Java Nacos
【实战攻略】破解Dubbo+Nacos+Spring Boot 3 Native打包后运行异常的终极秘籍——从零开始彻底攻克那些让你头疼不已的技术难题!
【8月更文挑战第15天】Nacos作为微服务注册与配置中心受到欢迎,但使用Dubbo+Nacos+Spring Boot 3进行GraalVM native打包后常遇运行异常。本文剖析此问题及其解决策略:确认GraalVM版本兼容性;配置反射列表以支持必要类和方法;采用静态代理替代动态代理;检查并调整配置文件;禁用不支持的功能;利用日志和GraalVM诊断工具定位问题;根据诊断结果调整GraalVM配置。通过系统排查方法,能有效解决此类问题,确保服务稳定运行。
19 0
|
1月前
|
监控 Java 微服务
Spring Boot微服务部署与监控的实战指南
【7月更文挑战第19天】Spring Boot微服务的部署与监控是保障应用稳定运行和高效维护的重要环节。通过容器化部署和云平台支持,可以实现微服务的快速部署和弹性伸缩。而利用Actuator、Prometheus、Grafana等监控工具,可以实时获取应用的运行状态和性能指标,及时发现并解决问题。在实际操作中,还需根据应用的具体需求和场景,选择合适的部署和监控方案,以达到最佳效果。
|
1月前
|
Java Spring
在Spring Boot中使用AOP实现日志切面
在Spring Boot中使用AOP实现日志切面