Spring 4 Dynamic Bean Creation - java

Maybe I'm not using the right terminology and that's why i can't find an answer, but I want to know how can I take information from a database to create beans that I can inject into the application?
Here's an example, rather than having this coded in a configuration file, I would like to possibly loop some values stored in a database and build these beans based on that:
#Bean
public CronTriggerFactoryBean cronTriggerFactoryBean() {
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactoryBean().getObject());
factory.setStartDelay(3000);
factory.setCronExpression("0 0/2 * 1/1 * ? *");
return factory;
}
How can I build beans like this and have them become a part of the application?

There are probably multiple ways how to achieve that, but all of them are pretty complex with a lots of pitfalls. I would say that in your example you should not create triggers as separate beans but rather have a single service to manage your schedules (and leave it out of Spring).
The thing with Spring is, that it is not designed to act as a dynamic container (like OSGi for example). This means that for example #Autowired dependencies are initialized during context startup and stays the same till the application context is destroyed.
However it is possible to construct bean definitions on the fly during initialization. Best place would be BeanFactoryPostProcessor. But this would be called during context initialization. This means you will have no other beans available (like EntityManager, DataSource, ...).
Another possibility is to somehow take advantage of context hierarchy. You can create and destroy application contexts on-the-fly. However implementing that would require deeper knowledge of Spring's internals.
Question for others: not sure if it is possible to reference initialized beans from parent context during child context initialization.

After you load the necessary bean properties from Database , use BeanDefinitionBuilder. You can refer this link

Related

Weld: Inject dependency inside Thread J2EE

I'm currently going into a huge problem and any help would be highly appreciated.
First of all, the following is occuring in a J2EE environment and I know I shouldn't be managing a Thread myself, but unfortunately I can't change that nor use EJB. The environment is based on the Tomcat Web Container and Weld CDI manager.
My structure contains lots of RESTful services, Service layer and DAO layer implementations, and all of them are getting one another injected by using
#Inject and it works fine. The issue comes when I need to get my Service layer injected into my Run method and I get
WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped.
I already have a method to return the desired bean with its contextual, as the following code describes:
BeanManager manager = (BeanManager) jndiContext.lookup("java:/comp/BeanManager");
Bean<T> bean = (Bean<T>) manager.getBeans(beanClass).iterator().next();
CreationalContext<?> ctx = manager.createCreationalContext(bean);
return (T) manager.getReference(bean, beanClass, ctx);
But even I use this method I get the error. So, is there any way in which I could inject my beans inside a Thread created and managed by me?
Thank you.
Sorry, but nope - this just won't work.
CDI, as it is, does not support context propagation across threads. It is bound to one thread only. Having it otherwise would present a severe overhead due to synchronization.
As a proof of my thread-bound claim above, look at Weld source code, where there is ThreadLocal<BeanStore> used as a storage for beans in given context. The class I refer to in the link is a predecessor to context implementing classes. Also note that this is not Weld-only "problem", any CDI impl out there work on the same basis.
You could activate given Context/Scope in a different thread but that means everything will be created anew and any state you had saved in your (for instance) #ApplicationScoped bean, will not propagate. Also, with some definitely not nice hacking, you might be able to access the bean store and make a copy to the other thread. That would give you a read-only access but I am not sure how to do that and if that's even worth the efforts.
Last but not least, CDI allows you to implements you own context or even supplement your version of built-in contexts. That way you would be able to provide a full-blown version of context working across threads, but there are so many challenged to it, that I am not sure it's doable/reasonable.

How to register an existing bean in Application context and what is the advantage I get out of it?

I am a newbie to Spring. I was going through spring documentation where it says we can register existing objects created outside spring container in application context. I did that like this
OutsideBean outsideBean = new OutsideBean();
ConfigurableApplicationContext applicationContext =
new ClassPathXmlApplicationContext("spring.xml");
// SpringBean is the bean which is defined in spring.xml
SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
ConfigurableListableBeanFactory configurableListableBeanFactory =
applicationContext.getBeanFactory();
configurableListableBeanFactory.registerSingleton("outsideBean", outsideBean);
I have many unanswered questions here.
The way I am doing above, is it correct.?
Even if it is correct, is it the best way to do that.?
What if I have to register a bean as a 'prototype'.?
By registering my bean in application context what is the advantage I get out of it.?
I read through many links in stackoverflow but couldnt understand it. Hence asking it in new thread.
AFAIK, yes
No, it's not the best way. The best way is to create the context from a Spring configuration class, and to create beans in this configuration class, using #Bean annotated methods, as described in the documentation. Or simply by annotating your class with #Component and letting Spring find your bean by classpath scanning.
Your specify a scope using the #Scope annotation
The advantage is that the bean is managed by Spring, and can thus be injected by Spring in all the other beans. It can also be injected by any other bean. And it can benefit from AOP in order, for example, to provide transactional methods.
Well prasad, to understand what is applicationcontext / bean / what will you get out of it you need to go through the basic architecture of Spring framework, Spring literally stands out when compared other java frameworks, as its DI (Dependency Injection) & IOC (Inversion of control) container features.
Rod Johnson laid the foundation for Spring in his Expert One-on-One J2EE Design and Development (http://as.wiley.com/WileyCDA/WileyTitle/productCd-0764543857.html) way back in 2002. Which suggested framework specific free POJO's power to enhance modern enterprise application developement.
Kindly go through foll. link, to know about DI & IOC.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/overview.html
TO answer your questions.
The way I am doing above, is it correct
Well technically what you did will work definitely. But Spring provides no. of combination to define a object as a bean.
Even if it is correct, is it the best way to do that.?
I suggest you define all your beans in XML document or annotate the class which u want as a bean with #Component annotation or you can omit XML file do away everything with Java configuration file (which i have not really tried).
What if I have to register a bean as a 'prototype'.?
Can you please elaborate what u mean by Prototype
By registering my bean in application context what is the advantage I get out of it.?
If you understand the essence of DI u will easily answer this question by yourself. As mentioned earlier for DI spring provides IOC factory called BeanFactory (its an interface go thorough docs, there are many implementation BeanFactory, ApplicationContext is one of them). So if you configure a object as a bean u can ask factory to give to u at any no of times with its properties are again loosely coupled with one or more beans in container.

Alternative to Spring's #Configurable for performance reasons?

I am using #Configurable beans for non-managed spring instances in a section of code that must be highly performant. We are using a lot of non-managed beans with the new operator, and in our profiling we have noticed that the use of the #Configurable annotation is slowing things down quite a bit.
Just for this specific section, we would like a faster way of pulling beans from the context (just a direct applicationContext.getBean()). I know we give up IoC doing this, but this is a special scenario and not a normal pattern.
We are using CTW for the weaving, but I wanted to know what mechanism spring is using behind the scenes to get the application context so we can simply grab it and use getBean? A static application context? Is it stored in threadlocal somewhere?
Aspects are singletons managed by AspectJ. When you put an aspect in your Spring configuration file Spring doesn't actually create the aspect. Instead it obtains a reference to the aspect using aspectOf().
This means that (at compile time when you do your weaving) your #Configurable annotation gets hooked into the singleton AnnotationBeanConfigurerAspect. Then when you load your application context, Spring obtains a reference to that same singleton aspect and calls the setBeanFactory() method on the aspect (since it implements BeanFactoryAware).
This magic can lead to trouble of course. If you had two application contexts then the second would overwrite the configuration of the first which can be terribly confusing.
To answer your question directly this means that all you have to do is create a new aspect that implements BeanFactoryAware (here is the code for AnnotationBeanConfigurerAspect which you can use as an example) and then "instantiate" that same aspect in your spring configuration file and your aspect will now have access to the bean factory.
If you're going for performance then please note that the above is not much cleaner than creating a static reference to the BeanFactory and instantiating that when you start your application so you might as well do the static reference as it is simpler.

How to create session beans after context initializations

I have following problem. I have a Vaadin/Spring application. All the business logic and data come from a different system and my application is using REST service clients for accessing these data. I have a lot of components, where I need these service clients.
I have a singleton class (kind of helper), that can provide beans from the Spring context. I would like to have my service client beans in this context, too, and just call getBean(beanId) on my helper class in my components. However, they should be first initialized after the user logs into the application (or even better, when they are first accessed). I don't want to create objects of my service clients in each component I need them and I also don't want to pass those objects through component constructors or methods.
Could someone point me the right directions???
The default Spring configuration is for Eager Initialization - i.e. singletons are initialized as the ApplicationContext is started, by defining the spring beans with Lazy Initialization. That way way, they should only be initialized when requested.

How is dependency injection working?

I am reading the Pro Spring 2.5 book and I have a question to how dependency injection works.
I understand the BeanFactory and doing dependency lookups. Now I read about dependency injection and I have some questions. Based on what I understand you want to limit the lookups to the minimum such as looking up an object for boot strapping the application. Then dependency injection will take care of the rest. However I don't understand this works.
Let say you have a beanfactory, you get an MyApplication instance that starts the whole application. The rest of the objects use dependency injection to get their collaborators. The beanfactory maintains the list of beans it manages but isn't this factory only available in the main method of the application? And if the beanfactory also manages the scope of their containing beans I don't understand how that is done. Are the beanfactory global in some way?
The bean factory instantiates all objects. It parses your configuration (xml or annotations), instantiates your beans and sets their dependencies. Then all these beans are stored in the application context.
You usually have an entry point to your application - there you do context.getBean(..). Now that bean has its dependencies injected, because it is put in the context by the bean factory.
The rule of thumb that will probably clear things: you never use the new operator (with bean classes) when using a DI framework. The framework makes the instances, not you.
So, there are two ways this can happen (as of Spring 3). In "traditional" dependency injection, the bean factory can only inject dependencies into beans it creates itself. In this scenario, the bean factory will resolve and inject all dependencies of a bean when that bean is first created.
The other way requires you to employ "full" AspectJ with either load- or compile-time weaving. In this scenario, you use an aspect in the spring-aspects.jar that basically pointcuts all new operations, allowing you to get dependency injection in arbitrarily created objects. This is triggered by using the #Configurable annotation. You can read more here.
The whole point on inversion of control and dependency injection is that you (typically) don't need the beanfactory except to get your application started. Your dependencies "automatically appear" in your objects. This is basically intended for objects with very few, typically one, instance during the whole lifetime of your application.
E.g. if your MyApplication depends on an instance of MyModuleA, you can simply have it #Autowired. When you fetch the application object from beanfactory at start time it already comes with an instance of MyModuleA preset.
About the scopes: this comes from web context. Besides objects with only one instance ever you can have objects scoped to a user's session. There you can store information you need to keep over several requests but separate for different users, think: shopping cart.
Typically treat the bean factory as global. I think it would be possible to have several instances, but they would be disconnected and can't inject objects only known to other instances.

Categories