Instantiating spring beans in dynamically created classes
I am dynamically creating classes which contain spring beans, however the beans are not getting instantiated or initialised, leaving them as null.
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(st开发者_Python百科rClassName);
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.
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.
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, 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.
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);
And you will have your dependencies set, without having your new class registered as a bean.
You need Spring container to instantiate the class than using reflection to instantiate. To make a bean scoped to prototype use the following syntax:
<bean id="prototypeBean" class="xyz.PrototypeBean" scope="prototype">
<!-- inject dependencies here as required -->
</bean>
Then instantiate prototype bean using the following code:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext ( "applicationContext.xml" );
PrototypeBean prototypeBean = ( PrototypeBean ) applicationContext.getBean ( "prototypeBean" );
精彩评论