<?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>Fri, 24 Sep 2010 07:42:49 +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(MyClass.class); 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>
<pre>private Log log = LogFactory.getLog(MyClass.class);</pre>
<p>you can write:</p>
<pre>@Logger private Log log;</pre>
<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>
<pre>
package com.tzavellas.spring.logger;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Logger { }
</pre>
<p>and now the <code>BeanPostProcessor</code>:</p>
<pre>
package com.tzavellas.spring.logger;

import java.lang.reflect.Field;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;

import static org.springframework.util.ReflectionUtils.FieldCallback;

public class LoggerPostProcessor implements BeanPostProcessor {

  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }

  public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        if (field.getAnnotation(Logger.class) != null) {
          Log log = LogFactory.getLog(bean.getClass());
          field.set(bean, log);
        }
      }
    });
    return bean;
  }
}
</pre>
<p>Below I have a small <a href="http://www.junit.org">JUnit</a> test to verify that it works:</p>
<pre>
package com.tzavellas.spring.logger;

import static org.junit.Assert.*;

import org.apache.commons.logging.Log;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class LoggerPostProcessorTest {

  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

  @Before
  public void setupFactory() {
    RootBeanDefinition bean = new RootBeanDefinition(Bean.class, true);
    factory.addBeanPostProcessor(new LoggerPostProcessor());
    factory.registerBeanDefinition("bean", bean);
  }

  @Test
  public void injectLogger() {
    Bean b = (Bean) factory.getBean("bean");
    assertNotNull(b.log);
    b.doSomething();
  }
}

class Bean {

  @Logger Log log;

  public void doSomething() {
    log.debug("message");
  }
}
</pre>
<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>

