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。

目录
相关文章
|
6月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
692 0
|
10月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
1492 13
|
5月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
7月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
7月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
人工智能 自然语言处理 Java
Spring 集成 DeepSeek 的 3大方法(史上最全)
DeepSeek 的 API 接口和 OpenAI 是兼容的。我们可以自定义 http client,按照 OpenAI 的rest 接口格式,去访问 DeepSeek。自定义 Client 集成DeepSeek ,可以通过以下步骤实现。步骤 1:准备工作访问 DeepSeek 的开发者平台,注册并获取 API 密钥。DeepSeek 提供了与 OpenAI 兼容的 API 端点(例如),确保你已获取正确的 API 地址。
Spring 集成 DeepSeek 的 3大方法(史上最全)
|
11月前
|
缓存 安全 Java
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
1044 5
|
11月前
|
Java Spring 容器
两种Spring Boot 项目启动自动执行方法的实现方式
在Spring Boot项目启动后执行特定代码的实际应用场景中,可通过实现`ApplicationRunner`或`CommandLineRunner`接口完成初始化操作,如系统常量或配置加载。两者均支持通过`@Order`注解控制执行顺序,值越小优先级越高。区别在于参数接收方式:`CommandLineRunner`使用字符串数组,而`ApplicationRunner`采用`ApplicationArguments`对象。注意,`@Order`仅影响Bean执行顺序,不影响加载顺序。
877 2