Instantiating spring beans in dynamically created classes
java, spring
Solution
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 via `WebApplicationContextUtils.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 call `registerPrototype(..)` to register your classes in the context. If this doesn't work, use `GenericContext` and its `registerBeanDefinition(..)`
- get all the instances that match your type, using `appContext.getBeansOfType(yourclass)`; or if you just registered it and know its name - use just `appContext.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.
Problem
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(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.