GK63 2023-06-18 13:36 采纳率: 25%
浏览 37

spring 动态注入bean的问题?


声明一个A类和A的子类B,
在 
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法里执行

ConfigurableListableBeanFactory.destroyBean("a")
ConfigurableListableBeanFactory.registerSingleton("a",new B());
然后马上
Object bean = ConfigurableListableBeanFactory.getBean("a"),

获取的 bean 类型是B类了,
但是使用 

@Autowired 
A a;

获取的还是A类型,请问是哪里不对?
  • 写回答

3条回答 默认 最新

  • 竹山全栈 2023-06-18 14:18
    关注

    这个问题的原因在于,Spring 的自动注入是基于反射实现的,并不会直接访问容器内部管理的对象,而是访问一个代理对象(Proxy Object)。代理对象是一个中间层,实际指向的是目标对象(Target Object),代理对象主要负责执行相关的处理逻辑(如事务控制等)。

    在你的情况中,当你在 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法里执行 ConfigurableListableBeanFactory.registerSingleton("a", new B()); 时,虽然 A 类型的 Bean 已经被移除并被重新创建并注册为 B 类型的 Bean,但是因为之前已经通过 @Autowired 注解自动注入了一个 A 类型的 Bean,该 Bean 已经被实例化并被代理了,因此无法直接获取到新注册的 B 类型的 Bean。

    如果你想要获取到新注册的 B 类型的 Bean,可以直接使用容器获取服务(Service)的方式,而不是使用自动注入。你可以在 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法中直接获取容器对象 ApplicationContext 或者 BeanFactory,然后通过该对象获取新注册的 B 类型的 Bean,具体可以参考下面的代码示例:

    public class MyPostProcessor implements InstantiationAwareBeanPostProcessor {
    
        @Autowired
        private ApplicationContext applicationContext;
    
        public Object postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if("a".equals(beanName)) {
                ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
                beanFactory.destroyBean("a");
                beanFactory.registerSingleton("a", new B());
                Object beanObj = beanFactory.getBean("a");
                // 在这里可以直接使用 beanObj,它是新注册的 B 类型的 Bean
            }
            return bean;
        }
    }
    

    需要注意强制类型转换并不是推荐的方式,在 Spring 框架中,通常通过依赖注入的方式来获取 Bean 对象。这种方式是更加灵活和更容易管理 Bean 对象的。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月18日

悬赏问题

  • ¥100 ensp启动设备蓝屏,代码clock_watchdog_timeout
  • ¥15 Android studio AVD启动不了
  • ¥15 陆空双模式无人机怎么做
  • ¥15 想咨询点问题,与算法转换,负荷预测,数字孪生有关
  • ¥15 C#中的编译平台的区别影响
  • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?
  • ¥15 电脑蓝屏logfilessrtsrttrail问题
  • ¥20 关于wordpress建站遇到的问题!(语言-php)(相关搜索:云服务器)
  • ¥15 【求职】怎么找到一个周围人素质都很高不会欺负他人,并且未来月薪能够达到一万以上(技术岗)的工作?希望可以收到写有具体,可靠,已经实践过了的路径的回答?
  • ¥15 Java+vue部署版本反编译