【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
[鹿鼎记, 金庸]
相关文章
|
29天前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
2月前
|
监控 安全 Java
|
6月前
|
Java Spring
JDK动态代理和CGLIB动态代理的区别
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理: ● JDK动态代理只提供接口的代理,不支持类的代理Proxy.newProxyInstance(类加载器, 代理对象实现的所有接口, 代理执行器) ● CGLIB是通过继承的方式做的动态代理 , 如果某个类被标记为final,那么它是无法使用 CGLIB做动态代理的。Enhancer.create(父类的字节码对象, 代理执行器)
|
6月前
|
监控 Java API
JDK动态代理和CGLIB动态代理
Java动态代理允许在运行时创建代理对象,增强或拦截目标类方法的执行。主要通过两种方式实现:JDK动态代理和CGLIB动态代理。JDK动态代理基于接口,利用`java.lang.reflect.Proxy`类和`InvocationHandler`接口;CGLIB则通过字节码技术生成目标类的子类作为代理,适用于未实现接口的类。两者均用于在方法执行前后添加额外逻辑,如日志记录、权限控制等,广泛应用于AOP框架中。
204 2
|
7月前
|
XML 安全 Java
Spring AOP—深入动态代理 万字详解(通俗易懂)
Spring 第四节 AOP——动态代理 万字详解!
254 24
|
7月前
|
监控 Java API
JDK动态代理和CGLIB动态代理
Java动态代理允许在运行时创建代理对象,增强或拦截目标类的方法调用,无需修改原代码。它有两种主要实现方式:JDK动态代理和CGLIB动态代理。 - **JDK动态代理**:通过`java.lang.reflect.Proxy`类和`InvocationHandler`接口实现,适用于实现了接口的类。它在方法调用前后插入额外逻辑,如日志记录、权限控制等。 - **CGLIB动态代理**:基于字节码技术,为未实现接口的类生成子类作为代理,重写父类方法以添加增强逻辑。适用于没有接口的类,但要求目标类不能是`final`类或方法。
|
7月前
|
Java API 数据安全/隐私保护
探索Java动态代理的奥秘:JDK vs CGLIB
动态代理是一种在 运行时动态生成代理类的技术,无需手动编写代理类代码。它通过拦截目标方法的调用,实现对核心逻辑的 无侵入式增强(如日志、事务、权限控制等)。
187 0
探索Java动态代理的奥秘:JDK vs CGLIB
|
10月前
|
Java 开发者 Spring
Spring AOP深度解析:探秘动态代理与增强逻辑
Spring框架中的AOP(Aspect-Oriented Programming,面向切面编程)功能为开发者提供了一种强大的工具,用以将横切关注点(如日志、事务管理等)与业务逻辑分离。本文将深入探讨Spring AOP的底层原理,包括动态代理机制和增强逻辑的实现。
195 4
|
10月前
|
安全 Java 开发者
AOP中的JDK动态代理与CGLIB动态代理:深度解析与实战模拟
【11月更文挑战第21天】面向切面编程(AOP,Aspect-Oriented Programming)是一种编程范式,它通过将横切关注点(cross-cutting concerns)与业务逻辑分离,以提高代码的可维护性和可重用性。在Java开发中,AOP的实现离不开动态代理技术,其中JDK动态代理和CGLIB动态代理是两种常用的方式。本文将从背景、历史、功能点、业务场景、底层逻辑等多个维度,深度解析这两种代理方式的区别,并通过Java示例进行模拟和比较。
669 5
|
11月前
|
Java
【编程进阶知识】静态代理、JDK动态代理及Cglib动态代理各自存在的缺点及代码示例
本文介绍了三种Java代理模式:静态代理、JDK动态代理和Cglib动态代理。静态代理针对特定接口或对象,需手动编码实现;JDK动态代理通过反射机制实现,适用于所有接口;Cglib动态代理则基于字节码技术,无需接口支持,但需引入外部库。每种方法各有优缺点,选择时应根据具体需求考虑。
125 1