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。

目录
相关文章
|
8天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
10天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
28天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
35 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
13天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
26 1
|
18天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
28 1
|
24天前
|
存储 安全 Java
|
19天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
25 1
|
28天前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
9天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
21 0
|
16天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
20 0