在动态创建的类中实例化Spring Bean [英] Instantiating spring beans in dynamically created classes
问题描述
我正在动态创建包含Spring bean的类,但是并没有实例化或初始化bean,而是将它们保留为空.
I am dynamically creating classes which contain spring beans, however the beans are not getting instantiated or initialised, leaving them as null.
如何确保动态创建的类正确创建了所有其spring bean?
How do I make sure that a dynamically created class creates all of its spring beans properly?
这是我动态创建类的方式:
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);
}
}
这会将ctransform(类型为strClassName)内的所有spring bean对象保留为空.
This leaves all spring bean objects within ctransform (of type strClassName) as null.
推荐答案
每当实例化类时,它们都是不是春季管理的. Spring必须实例化类,以便它可以注入其依赖项.除了使用@Configurable
和<context:load-time-weaver/>
的情况例外,但这更像是一种hack,我建议您反对.
Whenever you instantiate classes, they are not spring-managed. Spring has to instantiate classes so that it can inject their dependencies. This with the exception of the case when you use @Configurable
and <context:load-time-weaver/>
, but this is more of a hack and I'd suggest against it.
相反:
- 使范围为
prototype
的bean
- 获取
ApplicationContext
(在网络应用中,这是通过WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
完成的) - 如果未注册类(并且我假设它们未注册),请尝试强制转换为
StaticApplicationContext
(我不确定这是否可行),然后调用registerPrototype(..)
在上下文中注册您的类.如果这不起作用,请使用GenericContext
及其registerBeanDefinition(..)
- 使用
appContext.getBeansOfType(yourclass)
获取与您的类型匹配的所有实例;或者,如果您刚刚注册它并知道它的名称-请仅使用appContext.getBean(name)
- 确定哪一个适用.通常,
Map
中只有一个条目,请使用它.
- 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, useGenericContext
and 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.
但是我通常会避免对弹跳豆进行反思-应该有另一种方法来实现这一目标.
But I would generally avoid reflection on spring beans - there should be another way to achieve the goal.
更新:我只是想到了一个更简单的解决方案,该解决方案在不需要注册Bean的情况下也可以使用-即,您动态生成的类不会注入任何其他动态生成的类中课:
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:
// using WebApplicationContextUtils, for example
ApplicationContext appContext = getApplicationContext();
Object dynamicBeanInstance = createDyamicBeanInstance(); // your method here
appContext.getAutowireCapableBeanFactory().autowireBean(dynamicBeanInsatnce);
您将设置依赖项,而无需将新类注册为bean.
And you will have your dependencies set, without having your new class registered as a bean.
这篇关于在动态创建的类中实例化Spring Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!