java 将自定义 bean 添加到 Spring 上下文

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15720579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:38:12  来源:igfitidea点击:

Add custom beans to Spring context

javaspring

提问by Igor Artamonov

I have some classes, with a custom annotation, that shouldn't be instantiated (abstract class, and it's just a subcomponents for a real beans). But on top of this classes, on runtime, on context initialization phase, I want to put extra beans into application context.

我有一些类,带有自定义注释,不应实例化(抽象类,它只是真正 bean 的子组件)。但是在这些类之上,在运行时,在上下文初始化阶段,我想将额外的 bean 放入应用程序上下文中。

So, basically I need to scan classpath, process results, and introduce new beans into curent application context.

所以,基本上我需要扫描类路径,处理结果,并将新的 bean 引入当前的应用程序上下文。

It seems that spring-mvc, spring-tasks and spring-integration are doing this (I tried to learn it from sources - no luck)

似乎 spring-mvc、spring-tasks 和 spring-integration 正在这样做(我试图从源代码中学习它 - 没有运气)

I found that I can create my own BeanFactoryPostProcessor, scan classpath and call registerSingletonfor my custom bean. But I'm not sure that it's a good way for introducing new beans (seems that it's used only for postprocess of exising beans only). And I believe there are some Spring internal tools that I may reuse to simplify process.

我发现我可以创建自己的BeanFactoryPostProcessor、扫描类路径并调用registerSingleton我的自定义 bean。但我不确定这是引入新豆的好方法(似乎它仅用于现有豆的后处理)。而且我相信我可以重用一些 Spring 内部工具来简化流程。

What is a conventional way to introduce extra beans on Spring context initialization?

在 Spring 上下文初始化中引入额外 bean 的常规方法是什么?

采纳答案by Biju Kunjummen

Your observation is actually correct, BeanFactoryPostProcessoris one of the two ways Spring provides a mechanism to modify the bean definition/instances before making them available to the application(the other is using BeanPostProcessors)

您的观察实际上是正确的,BeanFactoryPostProcessor是 Spring 提供一种机制来修改 bean 定义/实例在将它们提供给应用程序之前的两种方式之一(另一种是使用BeanPostProcessors

You can absolutely use BeanFactoryPostProcessors to add/modify bean definitions, here is one sample from Spring Integration codebase that adds a errorChannel if not explicitly specified by a user, you can probably use a similar code for registering your new beans:

您绝对可以使用 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);

回答by Jose Luis Martin

There are at least two ways to include custom annotated classes as bean definitions:

至少有两种方法可以将自定义注释类包含为 bean 定义:

  • Annotate the custom annotation with @Component
  • Add a include filter with type annotation to <context:component-scan/>
  • 使用@Component 注释自定义注解
  • 添加带有类型注释的包含过滤器 <context:component-scan/>

for example:

例如:

<context:component-scan base-package="org.example">
        <context:include-filter type="annotation" expression="org.example.Annotation"/>
</context:component-scan>

Then you can use a BeanPostProcessorto instantiate them, for example:

然后你可以使用 aBeanPostProcessor来实例化它们,例如:

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;
            } 
    }

Or use a BeanFactoryPostProcessorto process the ScannedGenericBeanDefinitions.

或者使用 aBeanFactoryPostProcessor来处理ScannedGenericBeanDefinitions.

See AnnotationConfigUtils.registerAnnotationConfigProcessors()for sample code of internal Spring annotation postprocessors.

有关AnnotationConfigUtils.registerAnnotationConfigProcessors()内部 Spring 注释后处理器的示例代码,请参见。