Spring Bean 方法的可见性要求以进行 Spring AOP 代理

简介: 【8月更文挑战第22天】

Spring AOP 使用代理来拦截和修改方法调用。因此,要对 Spring bean 方法应用 AOP,这些方法必须具有适当的可见性,以便代理可以访问它们。

方法可见性要求

Spring AOP 对被代理方法的可见性有以下要求:

  • 对于 JDK 动态代理,方法必须是 public,因为动态代理只能代理 public 方法。
  • 对于 CGLIB 代理,方法可以是任何可见性,包括 public、protected、default(包)和 private。

为什么需要这些可见性要求?

这些可见性要求是由于 Spring AOP 使用不同的技术来创建代理:

  • JDK 动态代理:JDK 动态代理创建代理对象,其中包含目标对象方法的增强版本。由于代理对象必须能够调用目标对象的方法,因此目标对象的方法必须是 public。
  • CGLIB 代理:CGLIB 代理创建目标类的子类,其中覆盖目标对象的方法并插入自定义逻辑。由于子类可以访问父类的方法,因此 CGLIB 代理可以代理任何可见性的方法,包括 private 方法。

例外情况:

在某些情况下,即使方法不是 public,也可以使用 Spring AOP 对其进行代理:

  • 接口方法:接口方法始终是 public 的,因此可以使用 JDK 动态代理对其实现进行代理,即使实现方法不是 public。
  • final 方法:虽然 JDK 动态代理无法代理 final 方法,但 CGLIB 代理可以,因为 CGLIB 创建子类并覆盖方法。

建议的最佳实践

为了确保 Spring AOP 能够成功代理方法,建议将被代理方法声明为 public。这将确保无论使用哪种代理类型,都可以对方法进行代理。

示例

以下示例演示了如何使用不同可见性的方法以及如何使用 Spring AOP 对它们进行代理:

// public 方法
public void publicMethod() {
   
    // do something
}

// protected 方法
protected void protectedMethod() {
   
    // do something
}

// default(包)方法
void defaultMethod() {
   
    // do something
}

// private 方法
private void privateMethod() {
   
    // do something
}

使用 JDK 动态代理:

// 只能代理 public 方法
MyBean bean = new MyBean();
AdvisedSupport advised = new AdvisedSupport();
advised.setTargetSource(new TargetSource(bean));
advised.addAdvice(new MyAdvice());
ProxyFactory factory = new ProxyFactory(advised);
MyBean proxy = (MyBean) factory.getProxy();
proxy.publicMethod(); // 可以调用

使用 CGLIB 代理:

// 可以代理任何可见性的方法
MyBean bean = new MyBean();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyBean.class);
enhancer.setCallback(new MyMethodInterceptor());
MyBean proxy = (MyBean) enhancer.create();
proxy.publicMethod(); // 可以调用
proxy.protectedMethod(); // 可以调用
proxy.defaultMethod(); // 可以调用
proxy.privateMethod(); // 可以调用

总结

Spring AOP 对要代理的方法的可见性有要求。对于 JDK 动态代理,方法必须是 public。对于 CGLIB 代理,方法可以是任何可见性。为了确保 Spring AOP 能够成功代理方法,建议将被代理方法声明为 public。

目录
相关文章
|
27天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
27天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
143 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
14天前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
14天前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
5天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
37 9
|
16天前
|
Java 应用服务中间件 Spring
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
|
17天前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
14天前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
4月前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
49 2
|
4月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
45 0