<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>spiros.blog() &#187; Seam</title>
	<atom:link href="http://www.tzavellas.com/techblog/tag/seam/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tzavellas.com/techblog</link>
	<description>Spiros Tzavellas’s blog, mostly on software development and Java.</description>
	<lastBuildDate>Sun, 22 Aug 2010 20:25:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Implementing Seam style @Logger injection with Spring</title>
		<link>http://www.tzavellas.com/techblog/2007/03/31/implementing-seam-style-logger-injection-with-spring/</link>
		<comments>http://www.tzavellas.com/techblog/2007/03/31/implementing-seam-style-logger-injection-with-spring/#comments</comments>
		<pubDate>Sat, 31 Mar 2007 13:23:44 +0000</pubDate>
		<dc:creator>spiros</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[Spring Framework]]></category>

		<guid isPermaLink="false">http://www.tzavellas.com/techblog/2007/03/31/implementing-seam-style-logger-injection-with-spring/</guid>
		<description><![CDATA[Seam provides a number of features to help programmers with the tedious but necessary logging. One of them is the @Logger annotation that is used to inject a Seam Log instance into a Seam component. For example instead of writing: private Log log = LogFactory.getLog&#40;MyClass.class&#41;; you can write: @Logger private Log log; and Seam will [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jboss.com/products/seam">Seam</a> provides a number of <a href="http://docs.jboss.com/seam/1.2.1.GA/reference/en/html/concepts.html#d0e3162">features</a> to help programmers with the tedious but necessary logging. One of them is the <code>@Logger</code> annotation that is used to inject a <a href="http://www.jboss.com/products/seam">Seam</a> Log instance into a <a href="http://www.jboss.com/products/seam">Seam</a> component. For example instead of writing:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> Log log = LogFactory.<span style="color: #006633;">getLog</span><span style="color: #009900;">&#40;</span>MyClass.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>you can write:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;">@<span style="color: #003399; font-weight: bold;">Logger</span> <span style="color: #000000; font-weight: bold;">private</span> Log log<span style="color: #339933;">;</span></pre></div></div>

<p>and <a href="http://www.jboss.com/products/seam">Seam</a> will inject an appropriate logger. Below we will try to to implement this feature using the <a href="http://springframework.org/">Spring Framework</a> for objects managed by the Spring DI container (actually a  <a href="http://www.springframework.org/docs/api/org/springframework/beans/factory/BeanFactory.html"><code>BeanFactory</code></a>).</p>
<p>The Spring DI container provides a number of extension interfaces that beans can implement to get callbacks from the container in various stages of the container operation. One callback interface is the <a href="http://www.springframework.org/docs/api/org/springframework/beans/factory/config/BeanPostProcessor.html"><code>BeanPostProcessor</code></a>. <a href="http://www.springframework.org/docs/api/org/springframework/beans/factory/config/BeanPostProcessor.html"><code>BeanPostProcessor</code></a>s are called before and after the initialization of each bean and allow the custom modification of bean instances (for example wrapping an instance with a <a href="http://java.sun.com/j2se/1.3/docs/guide/reflection/proxy.html">dynamic proxy</a>).</p>
<p>The only thing we have to do to implement the <code>@Logger</code> injection (besides defining a <code>@Logger</code> annotation) is to write a <a href="http://www.springframework.org/docs/api/org/springframework/beans/factory/config/BeanPostProcessor.html"><code>BeanPostProcessor</code></a> that, before each bean gets initialized (right after it gets constructed), will iterate over the fields of the bean to detect any <code>@Logger</code> annotations and construct and inject a new logger instance.</p>
<p>Let&#8217;s define the annotation:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tzavellas.spring.logger</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">annotation</span>.<span style="color: #003399; font-weight: bold;">ElementType</span>.<span style="color: #006633;">FIELD</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> java.<span style="color: #006633;">lang</span>.<span style="color: #006633;">annotation</span>.<span style="color: #003399; font-weight: bold;">RetentionPolicy</span>.<span style="color: #006633;">RUNTIME</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.lang.annotation.Documented</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.lang.annotation.Retention</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.lang.annotation.Target</span><span style="color: #339933;">;</span>
&nbsp;
@<span style="color: #003399; font-weight: bold;">Retention</span><span style="color: #009900;">&#40;</span>RUNTIME<span style="color: #009900;">&#41;</span>
@<span style="color: #003399; font-weight: bold;">Target</span><span style="color: #009900;">&#40;</span>FIELD<span style="color: #009900;">&#41;</span>
@<span style="color: #003399; font-weight: bold;">Documented</span>
<span style="color: #000000; font-weight: bold;">public</span> @<span style="color: #000000; font-weight: bold;">interface</span> <span style="color: #003399; font-weight: bold;">Logger</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>and now the <code>BeanPostProcessor</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tzavellas.spring.logger</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.lang.reflect.Field</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.commons.logging.Log</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.commons.logging.LogFactory</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.BeansException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.factory.config.BeanPostProcessor</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.util.ReflectionUtils</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">springframework</span>.<span style="color: #006633;">util</span>.<span style="color: #006633;">ReflectionUtils</span>.<span style="color: #006633;">FieldCallback</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LoggerPostProcessor <span style="color: #000000; font-weight: bold;">implements</span> BeanPostProcessor <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">Object</span> postProcessAfterInitialization<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Object</span> bean, <span style="color: #003399; font-weight: bold;">String</span> beanName<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> BeansException <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> bean<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">Object</span> postProcessBeforeInitialization<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399; font-weight: bold;">Object</span> bean, <span style="color: #003399; font-weight: bold;">String</span> beanName<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> BeansException <span style="color: #009900;">&#123;</span>
    ReflectionUtils.<span style="color: #006633;">doWithFields</span><span style="color: #009900;">&#40;</span>bean.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> FieldCallback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> doWith<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Field</span> field<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399; font-weight: bold;">IllegalArgumentException</span>, <span style="color: #003399; font-weight: bold;">IllegalAccessException</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000;  font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>field.<span style="color: #006633;">getAnnotation</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Logger</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          Log log = LogFactory.<span style="color: #006633;">getLog</span><span style="color: #009900;">&#40;</span>bean.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          field.<span style="color: #006633;">set</span><span style="color: #009900;">&#40;</span>bean, log<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> bean<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Below I have a small <a href="http://www.junit.org">JUnit</a> test to verify that it works:</p>

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.tzavellas.spring.logger</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">junit</span>.<span style="color: #006633;">Assert</span>.<span style="color: #339933;">*;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.commons.logging.Log</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.junit.Before</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.junit.Test</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.factory.support.DefaultListableBeanFactory</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.factory.support.RootBeanDefinition</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LoggerPostProcessorTest <span style="color: #009900;">&#123;</span>
&nbsp;
  DefaultListableBeanFactory factory = <span style="color: #000000; font-weight: bold;">new</span> DefaultListableBeanFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  @Before
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> setupFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    RootBeanDefinition bean = <span style="color: #000000; font-weight: bold;">new</span> RootBeanDefinition<span style="color: #009900;">&#40;</span>Bean.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #006600; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    factory.<span style="color: #006633;">addBeanPostProcessor</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> LoggerPostProcessor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    factory.<span style="color: #006633;">registerBeanDefinition</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bean&quot;</span>, bean<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Test
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> injectLogger<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Bean b = <span style="color: #009900;">&#40;</span>Bean<span style="color: #009900;">&#41;</span> factory.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;bean&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertNotNull<span style="color: #009900;">&#40;</span>b.<span style="color: #006633;">log</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    b.<span style="color: #006633;">doSomething</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Bean <span style="color: #009900;">&#123;</span>
&nbsp;
  @<span style="color: #003399; font-weight: bold;">Logger</span> Log log<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> doSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> log.<span style="color: #006633;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;message&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This is a very simple implementation since the goal of this article is to demonstrate the extensibility of the Spring DI container and not to implement a complete solution. One limitation is that this implementation only injects loggers (actually commons-logging Logs) to public fields (Seam can inject Seam Logger to private fields).</p>
<p>To use the above in a Spring XML file you simply define a bean with class <code>com.tzavellas.spring.logging.LoggerPostProcessor</code> (the id/name is not needed). The <code>BeanFactory</code>/<code>ApplicationContext</code> will automatically detect all beans that implement the <code>BeanPostProcessor</code> interface at startup time and will initialize them and then call them every time a bean gets initialized.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tzavellas.com/techblog/2007/03/31/implementing-seam-style-logger-injection-with-spring/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
