我有一些带有自定义注释的类,它们不应该被实例化(抽象类,它只是真正的bean的子组件)。但是在这些类之上,在运行时,在上下文初始化阶段,我想将额外的bean放入应用程序上下文中。
所以,基本上我需要扫描类路径,处理结果,并将新的bean引入curent应用程序上下文。
看起来spring-mvc,spring-tasks和spring-integration正在这样做(我试图从源头学习它 - 没有运气)
我发现我可以创建自己的BeanFactoryPostProcessor
,扫描类路径并为我的自定义bean调用registerSingleton
。但是我不确定这是引入新bean的好方法(似乎它只用于exce beans bean的后期处理)。我相信有一些Spring内部工具可以重复使用以简化流程。
在Spring上下文初始化中引入额外bean的传统方法是什么?
答案 0 :(得分:4)
您的观察实际上是正确的,BeanFactoryPostProcessor是Spring提供一种机制来修改bean定义/实例的两种方式之一,然后再将它们提供给应用程序(另一种方法是使用BeanPostProcessors)< / p>
你绝对可以使用BeanFactoryPostProcessors来添加/修改bean定义,这里有一个来自Spring Integration代码库的示例,如果没有用户明确指定,它会添加一个errorChannel,你可以使用类似的代码来注册你的新bean:
RootBeanDefinition errorChannelDef = new RootBeanDefinition();
errorChannelDef.setBeanClassName(IntegrationNamespaceUtils.BASE_PACKAGE
+ ".channel.PublishSubscribeChannel");
BeanDefinitionHolder errorChannelHolder = new BeanDefinitionHolder(errorChannelDef,
IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(errorChannelHolder, registry);
答案 1 :(得分:2)
至少有两种方法可以将自定义带注释的类包含为bean定义:
<context:component-scan/>
例如:
<context:component-scan base-package="org.example">
<context:include-filter type="annotation" expression="org.example.Annotation"/>
</context:component-scan>
然后您可以使用BeanPostProcessor
来实例化它们,例如:
public class CustomAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass.isAnnotationPresent(org.example.Annotation.class)) {
Object bean = createBeanInstance();
...
return bean:
}
return null;
}
}
或使用BeanFactoryPostProcessor
处理ScannedGenericBeanDefinitions
。
有关内部Spring注释后处理器的示例代码,请参阅AnnotationConfigUtils.registerAnnotationConfigProcessors()
。
答案 2 :(得分:1)
答案 3 :(得分:1)
请参阅此链接有关BeanPostProcessors&amp; BeanFactoryPostProcessor的 http://springindepth.com/book/in-depth-ioc-bean-post-processors-and-beanFactory-post-processors.html