Framework

Arid POJOs Framework

jeeyong 2008. 4. 11. 14:09

Simplifying Spring's XML-based dependency injection



XML Spring bean definitions can be verbose. However, an important benefit of using XML is that it completely decouples the components that are being assembled from the mechanism that is assembling them. This is an important part of the POJO programming model and would allow, for example, Spring to be easily replaced by some other framework. This is not true when using annotation-based dependency injection such as that provided by the Guice framework. Components that use those kinds of annotations are tightly coupled to the framework and are definitely not POJOs!

So how can we use a more concise form of XML for configuring dependency injection? In my recent projects, most components had pretty simple wiring rules, e.g. services are injected with repositories; repositories are injected with the SessionFactory or HibernateTemplate etc. Moreover, there is usually a single instance of each bean class and so it's possible to autowire components. We could, therefore, define each service with something like this:

<bean name="fooService" autowire="constructor"  class="FooServiceImpl"/>

This is certainly easier that writing multiple <constructor-arg> elements and updating them as the class changes. But we would have to write and maintain similar XML for every component. Why not go one step further and write a "rule" to define beans for all of the components?

Writing "rules" to configure multiple beans

Here is an example of such a "rule":


<beans>

<arid:define-beans

   package="net.chrisrichardson.arid.example.dao"

  autowire="byType"

/>

</beans>


The <arid:define-beans> element (arid is a custom Spring XML namespace) generates bean definitions that use byType autowiring for all of the concrete classes in the net.chrisrichardson.arid.example.dao package. Each bean would, for example, be injected with a Hibernate SessionFactory. The bean name is derived from the concrete class name using a pluggable algorithm - the default algorithm generates a bean called accountDao for the class AccountDaoImpl.

Using AspectJ type patterns

We can be a little more selective about which classes to define as Spring beans by using the <arid:define-beans> element's pattern attribute. This attribute is an AspectJ type pattern. We can use it to match against class names, classes annotations etc. Here is an example of that:


<arid:define-beans

package="net.chrisrichardson.arid.example.domain"

pattern="@ServiceImpl *..*">


</arid:define-beans>

This definition looks for classes in the net.chrisrichardson.arid.example.domain package that have the application-defined @ServiceImpl annotation (package name omitted for brevity) and defines beans that use constructor autowiring. Each bean would, for example, be injected with the necessary DAOs.

Handling special cases

But wait, there is more! Let's suppose that one of the classes needs to be injected with some property value. One option is to write a regular bean definition that overrides the definition generated by <arid:define-beans>. Alternatively, you can use <arid:extras> element. In the following example, the moneyTransferService bean uses constructor autowiring and setter injection for the foo property.


<arid:define-beans

package="net.chrisrichardson.arid.example.domain"

pattern="@ServiceImpl *..*">

    <arid:extras>

<bean name="moneyTransferService">

    <property name="foo" value="bar" />

</bean>

     </arid:extras>

</arid:define-beans>

The Spring bean definitions defined by <arid:extras> are merged with the autogenerated bean definition. I'm not sure whether this is worthwhile since it only saves you having to specify the class and autowire attributes but it's something to think about.

Summary

This approach can significantly reduce the amount of XML required to configure an application. However, how widely it can be used in your application depends on whether the same dependency injection rules can be consistently applied to multiple beans. Would this help simplify your application's Spring configuration files?


출처 : Chris Richardson - enterprise POJOs

'Framework' 카테고리의 다른 글

POI 3.5 beta1을 이용한 파일(DOC, XLS, XLSX) 내용 검색 예제  (0) 2011.06.29
Commons Logging과 Log4J  (0) 2011.05.24
심플한 LOG4J  (0) 2008.06.26
log4j 배워보자  (0) 2008.06.04
[apache]Log4J 설치 및 사용법  (0) 2008.03.08