Spring AOP代理在BeanPostProcessor与FactoryBean依赖下失效问题
问题:Spring AOP代理未生效(结合BeanPostProcessor与FactoryBean场景)
问题描述
当自定义BeanPostProcessor(MyPostProcessor)和FactoryBean(MyFactoryBean)结合使用时,Spring AOP无法为HelloService Bean生成代理,最终返回的是普通Java对象,无任何代理逻辑。
只有当BeanPostProcessor依赖另一个Bean(如本例中的GoodByeService)时,才会触发该问题。
预期行为
HelloService Bean应被AOP代理,以下检查需返回true:
AopUtils.isAopProxy(helloService)AopUtils.isJdkDynamicProxy(helloService)或AopUtils.isCglibProxy(helloService)
同时,调用HelloService的sayHello方法时,MyAspect中的@AfterReturning通知需被触发。
实际行为
HelloService Bean未被代理,以下检查均返回false:
AopUtils.isAopProxy(helloService)AopUtils.isJdkDynamicProxy(helloService)AopUtils.isCglibProxy(helloService)
且MyAspect中的@AfterReturning通知未被触发。
复现步骤
以下是最小可复现示例:
POM文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>spring-aop</artifactId> <parent> <groupId>com.cj.lb</groupId> <artifactId>spring-exploration</artifactId> <version>1.0-SNAPSHOT</version> </parent> <properties> <spring-versrion>6.0.11</spring-versrion> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-versrion}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring-versrion}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency> </dependencies> </project>
配置类
@EnableAspectJAutoProxy @Configuration @ComponentScan public class MyConfig { @Bean MyPostProcessor myPostProcessor(GoodByeService goodByeService) { MyPostProcessor myPostProcessor = new MyPostProcessor(); myPostProcessor.setGoodByeService(goodByeService); return myPostProcessor; } @Bean MyFactoryBean myFactoryBean(HelloService helloService) { MyFactoryBean myFactoryBean = new MyFactoryBean(); myFactoryBean.setHelloService(helloService); return myFactoryBean; } }
BeanPostProcessor实现类
public class MyPostProcessor implements Ordered, BeanPostProcessor { private GoodByeService goodByeService; public GoodByeService getGoodByeService() { return goodByeService; } public void setGoodByeService(GoodByeService goodByeService) { this.goodByeService = goodByeService; } @Override public int getOrder() { return 0; } }
服务类
@Service public class HelloServiceImpl implements HelloService { @Override public String sayHello() { String result = "hello world"; System.out.println(result); return result; } } @Service public class GoodByeServiceImpl implements GoodByeService { @Override public String sayGoodbye() { return "Goodbye"; } }
FactoryBean实现类
public class MyFactoryBean implements FactoryBean { private HelloService helloService; public HelloService getHelloService() { return helloService; } public void setHelloService(HelloService helloService) { this.helloService = helloService; } @Override public Object getObject() throws Exception { return new MyBean(); } @Override public Class<?> getObjectType() { return MyBean.class; } public static class MyBean { } }
切面类
@Component @Aspect public class MyAspect { @Pointcut("execution(* com.cj.lb.service.HelloService.sayHello(..))") public void pointcut() {} @AfterReturning(pointcut = "pointcut()", returning = "result") public void afterReturning(JoinPoint jp, Object result) { System.out.println("my aspect aop ..."); } }
主类
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); HelloService helloService = context.getBean(HelloService.class); System.out.println("helloService.getClass() = " + helloService.getClass()); System.out.println("Is AOP Proxy: " + AopUtils.isAopProxy(helloService)); System.out.println("Is JDK Dynamic Proxy: " + AopUtils.isJdkDynamicProxy(helloService)); System.out.println("Is CGLIB Proxy: " + AopUtils.isCglibProxy(helloService)); context.close(); } }
输出结果
helloService.getClass() = class com.cj.lb.service.impl.HelloServiceImpl Is AOP Proxy: false Is JDK Dynamic Proxy: false Is CGLIB Proxy: false
分析与解决方案
该问题可通过以下任一方式解决:
- 在
MyFactoryBean的HelloService依赖上添加@Lazy注解 - 为
MyFactoryBean添加正确的泛型声明(修改为public class MyFactoryBean implements FactoryBean<MyBean>)
疑问
- 为什么带有依赖的
BeanPostProcessor会影响HelloService的AOP代理创建? - 这是Spring的Bug,还是遗漏了特定的配置要求?
补充说明
该问题似乎与Bean初始化顺序或代理创建时机有关,尤其是涉及BeanPostProcessor和FactoryBean依赖时,希望得到进一步的澄清。
内容的提问来源于stack exchange,提问作者java-lbb
相关产品推荐
相关产品推荐

