如何向Spring非托管类中注入预先未知类型的Bean?
给非托管类注入Spring Bean的解决方案
当然可以!Spring早就考虑到了这种场景,提供了现成的API来帮你给非托管对象(也就是你自己通过new创建的对象)注入依赖,完全匹配你想要的beanInjector.injectBeans(instance)这种用法。
核心工具:AutowireCapableBeanFactory
Spring的AutowireCapableBeanFactory接口专门处理这类“非托管对象的依赖注入”需求,其中的autowireBean(Object existingBean)方法可以自动扫描对象上的@Resource、@Autowired等注解,将对应的Spring Bean注入到字段中。
具体实现代码
你只需要修改你的SomeAPIService,直接注入AutowireCapableBeanFactory替代你想象中的BeanInjector即可:
@Service public class SomeAPIService { @Resource private AutowireCapableBeanFactory autowireCapableBeanFactory; public void someProcessingFunction(Class<? extends APIClass> clazz) throws Exception { // 自己创建非托管对象实例 APIClass instance = clazz.getConstructor().newInstance(); // 关键一步:让Spring为这个对象注入依赖 autowireCapableBeanFactory.autowireBean(instance); // 现在对象的依赖已经注入完成,可以执行业务逻辑了 instance.executeBusinessStuffs(); } }
额外进阶:处理初始化回调
如果你的NonManagedClass里有@PostConstruct注解的初始化方法,想要让Spring自动执行它的话,可以使用initializeBean方法,它不仅会注入依赖,还会触发初始化回调:
public void someProcessingFunction(Class<? extends APIClass> clazz) throws Exception { APIClass instance = clazz.getConstructor().newInstance(); // 注入依赖 + 执行@PostConstruct方法 autowireCapableBeanFactory.initializeBean(instance, "customBeanName"); instance.executeBusinessStuffs(); }
这里的第二个参数是给这个对象指定一个Bean名称,如果你不需要的话可以传null。
注意事项
- 确保你的
Service1、Service2…ServiceN这些依赖类已经被Spring正确托管(比如添加了@Service、@Component等注解,并且被Spring扫描到)。 AutowireCapableBeanFactory是Spring上下文的核心组件,直接注入它是最规范的用法,不需要自己实现额外的注入工具类。
内容的提问来源于stack exchange,提问作者João Pedro Schmitt
相关产品推荐
相关产品推荐

