segunda-feira, agosto 07, 2006

A little bit about Spring 2.0



Yesterday I was playing a little bit around with the new features of Spring 2.0.
I would know how Spring Team can think in features that can improve more and more this framework that in my opinion is enough great.
I made some and I’m really surprised the ability to attach post-instantiation processors to beans which have NOT been instantiated by the Spring container. This means a lot to me when I started thinking about how this feature can add value to the current scheme of things in a POJO based Spring configured application.

Let’s straight to example:
public class Product {
// price
// getters and setters
// domain behavior
}
As you know, a typical domain object is instantiated in the application either from the ORM layer -read Hibernate through persistence services- or by the user using factories. Any sort of service injection that is done will be through hardwired code
public class Product {
// ...
public BigDecimal calculatePrice(...) {
BigDecimal productVendorsPrices =
VendorsRateDAO.getInstance().find(...);
// ...
}
// ...
}
The above domain class now has a hardwired dependency on the class VendorsRateDAO, which brings in all sorts of unwanted side-effects :

Domain layer should be persistence agnostic
The domain classes should be unit-testable without the service layer
Proliferation of business logic in the controllers
// Controller class for product entry use case
public class ProductService {
// ...
public void enterProduct(...) {
Product pr = ProductFactory.create(...);
//..
}
// ...
}


Wow, its smell so dirty code!! The domain model becomes anemic !.

Using Spring 2.0

Using the new extension of AOP in Spring 2.0, you can inject any object even if it has been created outside the control of the container.
Spring 2.0 offers annotation driven aspects towards this end as the most recommended approach towards dependency injection into the domain model. Let us see how the Product class changes :
@Configurable("product")
public class Product {
// ...
public BigDecimal calculatePrice (...) {
BigDecimal interest =
dao.find(...);
// ...
}
// ...

// injected DAO
private VendorsRateDao dao;
public void setDao(VendorsRateDao dao) {
this.dao = dao;
}
}


And the usual stuff in the XML for application context :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
...>

  <aop:spring-configured/>

  <bean id="vendorsRateDAO"
    class="org.javafree.dao.VendorsRateDaoImpl"/>

  <bean id="trade"
    class="org.javafree.model.Product"
    lazy-init="true">
    <property name="dao" ref="vendorsRateDAO" />
  </bean>
</beans>

Well, now that you know how Spring can lets you Architecture more cleaner, why are you using EJB yet?