如何在Spring中替换指定类的所有Bean实现为带Autowired的代理?
替换FooImpl实现的Fooable Bean为带Autowired依赖的代理类
需求
使用带有自定义逻辑和额外@Autowired Bean的FooProxy,替换所有由FooImpl实现的Fooable类型Bean。
现有代码
接口定义
public interface Fooable { void foo(); }
实现类
public class FooImpl implements Fooable { @Override public void foo() { throw new UnsupportedOperationException(); } public void foo2() { //do smth } }
代理类
public class FooProxy implements Fooable { private final FooImpl fooImpl; private final SomethingAutowired somethingAutowired; public FooProxy(FooImpl fooImpl, SomethingAutowired somethingAutowired) { this.fooImpl = fooImpl; this.somethingAutowired = somethingAutowired; } @Override public void foo() { fooImpl.foo2(); somethingAutowired.bar(); } }
配置类
@Configuration public class Config { @Bean public Fooable fooable1() { return new FooImpl(); } @Bean public Fooable fooable2() { return new FooImpl(); } }
已尝试方案及问题
- AOP:可实现需求,但不偏好此方式
- BeanPostProcessor(BPP):在
postProcessAfterInitialization中替换为代理类,但无法自动注入自定义Bean - BeanFactoryPostProcessor(BFPP):修改
setBeanClassName无效,且不适用于当前场景
优雅解决方案
使用BeanPostProcessor结合Spring容器的自动注入能力,直接在处理器中获取所需的SomethingAutowired Bean,然后创建并返回代理类实例:
@Component public class FooProxyReplacer implements BeanPostProcessor { private final SomethingAutowired somethingAutowired; // 直接通过构造器注入所需的Autowired Bean public FooProxyReplacer(SomethingAutowired somethingAutowired) { this.somethingAutowired = somethingAutowired; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // 仅对FooImpl类型的Bean进行替换 if (bean instanceof FooImpl) { return new FooProxy((FooImpl) bean, somethingAutowired); } return bean; } }
方案说明
- 该处理器本身是Spring管理的Bean,因此可以通过构造器自动注入
SomethingAutowired,无需手动处理依赖注入 - 在
postProcessAfterInitialization阶段,Spring已经完成了原FooImplBean的初始化,此时直接用它构造FooProxy并返回,即可完成替换 - 所有由
FooImpl实现的FooableBean都会被自动替换为FooProxy,无需修改原有配置类中的Bean定义
内容的提问来源于stack exchange,提问作者mxpnk
相关产品推荐
相关产品推荐

