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.

Original source