java 在动态创建的类中实例化 spring bean
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2867997/
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
Instantiating spring beans in dynamically created classes
提问by Xetius
I am dynamically creating classes which contain spring beans, however the beans are not getting instantiated or initialised, leaving them as null.
我正在动态创建包含 spring bean 的类,但是 bean 没有被实例化或初始化,将它们保留为 null。
How do I make sure that a dynamically created class creates all of its spring beans properly?
我如何确保动态创建的类正确创建了它的所有 spring bean?
This is how I am dynamically creating the class:
这就是我动态创建类的方式:
Class ctransform;
try {
ctransform = Class.forName(strClassName);
Method handleRequestMethod = findHandleRequestMethod(ctransform);
if (handleRequestMethod != null) {
return (Message<?>) handleRequestMethod.invoke(ctransform.newInstance(), message);
}
}
This leaves all spring bean objects within ctransform (of type strClassName) as null.
这将 ctransform(类型为 strClassName)中的所有 spring bean 对象保留为 null。
回答by Bozho
Whenever you instantiate classes, they are notspring-managed. Spring has to instantiate classes so that it can inject their dependencies. This with the exception of the case when you use @Configurableand <context:load-time-weaver/>, but this is more of a hack and I'd suggest against it.
当你实例化类,它们是不是春天的管理。Spring 必须实例化类,以便它可以注入它们的依赖项。除了您使用@Configurableand的情况外<context:load-time-weaver/>,这更像是一种黑客行为,我建议不要这样做。
Instead:
反而:
- make the bean of scope
prototype - obtain the
ApplicationContext(in a web-app this is done viaWebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)) - if the classes are not registered (and I assume they are not), try casting to
StaticApplicationContext(I'm not sure this will work), and callregisterPrototype(..)to register your classes in the context. If this doesn't work, useGenericContextand itsregisterBeanDefinition(..) - get all the instances that match your type, using
appContext.getBeansOfType(yourclass); or if you just registered it and know its name - use justappContext.getBean(name) - decide which one is applicable. Usually you will have only one entry in the
Map, so use it.
- 制作作用域的bean
prototype - 获取
ApplicationContext(在网络应用程序中,这是通过WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)) - 如果类未注册(我假设它们没有注册),请尝试强制转换为
StaticApplicationContext(我不确定这是否可行),然后调用registerPrototype(..)在上下文中注册您的类。如果这不起作用,请使用GenericContext及其registerBeanDefinition(..) - 使用
appContext.getBeansOfType(yourclass);获取与您的类型匹配的所有实例;或者,如果您刚刚注册并知道它的名称 - 只需使用appContext.getBean(name) - 决定哪一个适用。通常您在 中只有一个条目
Map,因此请使用它。
But I would generally avoid reflection on spring beans - there should be another way to achieve the goal.
但我通常会避免对春豆的反思 - 应该有另一种方式来实现目标。
Update:I just thought of an easier solution, that will work if you don't need to register the beans - i.e. that your dynamically generated classes won't be injected in any other dynamically generated class:
更新:我只是想到了一个更简单的解决方案,如果您不需要注册 bean,它将起作用 - 即您的动态生成的类不会被注入到任何其他动态生成的类中:
// using WebApplicationContextUtils, for example
ApplicationContext appContext = getApplicationContext();
Object dynamicBeanInstance = createDyamicBeanInstance(); // your method here
appContext.getAutowireCapableBeanFactory().autowireBean(dynamicBeanInsatnce);
And you will have your dependencies set, without having your new class registered as a bean.
并且您将设置依赖项,而无需将新类注册为 bean。
回答by Snehal
You need Spring container to instantiate the class than using reflection to instantiate. To make a bean scoped to prototype use the following syntax:
您需要 Spring 容器来实例化类,而不是使用反射来实例化。要使 bean 范围限定为原型,请使用以下语法:
<bean id="prototypeBean" class="xyz.PrototypeBean" scope="prototype">
<!-- inject dependencies here as required -->
</bean>
Then instantiate prototype bean using the following code:
然后使用以下代码实例化原型 bean:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext ( "applicationContext.xml" );
PrototypeBean prototypeBean = ( PrototypeBean ) applicationContext.getBean ( "prototypeBean" );

