Factories
In CDI there is @Producer, and in Guice there is the Provider<T> interface. These are very useful when you have some run-time decisions to make about what object to produce or how to configure it. So, how do you make a factory in Spring?Method 1 - Make a configuration bean
One simple way to create a factory in Spring is to add a @Configuration bean. Factory methods can be annotated with @Bean, and the factory method parameters will be injected. You will need to add CGLIB to your (run time) dependencies if you want this to work properly.- Make sure you have cglib in your dependency list.
- Add <context:annotation-config/> to your applicationContext.xml (or other XML configuration).
- Create a class in a package that is scanned for annotations, and annotate it with @Configuration.
- Each method in the @Configuration class that produces a bean should be annotated with @Bean. Parameters to the @Bean methods will be injected automatically, and can have @Value and @Qualifier annotations.
Method 2 - Make a factory bean / factory method
Another way is to use factory-bean and factory-method.- Register the factory bean. For example:
<bean id="thingFactory" class="eg.ThingFactory"/>
Where eg.ThingFactory has a method public Thing getThing()
- Register the produced object by referencing a method on the factory bean.
<bean id="thing" factory-bean="thingFactory" factory-method="getThing"/>
Spring will then call the getThing() method on the ThingFactory to get the instance.
Injecting values vs beans
In other DI frameworks, injecting a String is the same as injecting any other component.In the Spring bean XML format, there is a difference between injecting a "value" vs injecting another bean. To inject a bean, use ref="someBeanId" (a.k.a. bean 'name'). To inject a value, use value="some value or Spring EL".
Using Spring annotations, you can add
Transactional Beans
In EJB3, there are some simple transaction annotations that allow you to declare the transaction support you want for your business logic. Spring has a very similar feature.
@Transactional - provides transaction control. Very similar to EJB3 - class level and method level control.
<tx:annotation-driven/> enables the transaction annotation support.
You can also use TransactionTemplate for programmatic control when needed.
Post-Commit Actions and Transaction Synchronization
Use TransactionSynchronizationManager to get an interface that is similar to JTA Transaction.registerSynchronization(). Something like this:TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { void afterCommit() { // ... do stuff ... } });
A few notes on this:
- If this is used outside of a transaction, the method will fail. You can have it call the 'after commit' immediately if not inside a transaction, or just let it throw an error and fix the problem.
- TransactionSynchronizationManager is not an injectable thing. You have to use the static methods.
- TransactionSynchronizationAdapter is an empty implementation of TransactionSynchronization that you can use to override specific methods. Pretty handy.
Next Time...
In the next post I'll try to cover Extended Persistence Contexts and some of the web MVC stuff.
No comments:
Post a Comment