Mischiefblog
I make apps for other people

Notes on Spring development

Posted by Chris Jones
On August 15th, 2009 at 21:28

Permalink | Trackback | Links In |

Comments (3) |
Posted in General

3.0.0.M3 library problems
I haven’t tried 3.0.0.M4 with my new development environment yet, but I had missing class and Antlr problems with 3.0.0.M3. I ended up using 3.0.0.CI-319 at the time to get a working Spring framework.

Creating a logging bean
Create an annotation package with a Log interface:

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;
  
/**
* Injects a logger of an appropriate type into beans.
*/
@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Log {
  
}

Create a logger injector:

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
  
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;
  
/**
* Auto injects the commons Log implementation into the bean when a field is annotated
* with Logger.
*/
public class LoggerInjector implements BeanPostProcessor {
  private static Map>String , Logger< loggers = new HashMap>String , Logger<();
  
  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 {
        // make the field accessible if defined private
        ReflectionUtils.makeAccessible(field);
        if (field.getAnnotation(Log.class) != null) {
          String cls = bean.getClass().getName();
          field.setAccessible(true);
          Logger logger = null;
          if (loggers.containsKey(cls)) {
            logger = loggers.get(cls);
          } else {
            logger = Logger.getLogger(cls);
            loggers.put(cls, logger);
          }
          field.set(bean, logger);
        }
      }
    });
  
    return bean;
  }
}

Declare your logger bean in your application context:

<bean class="mypackage.annotation.LoggerInjector"/>

Attach the Logger to your class:

import org.apache.log4j.Logger;
 
import mypackage.annotation.Log;
 
// in your class fields
 
/**
* Logger
*/
@Log
private Logger logger;
 
// use it
logger.error("Invalid request type: " + requestType);

Interface-oriented design
Define your data objects and factories as interfaces (methods), then provide factory implementations to create or retrieve instances of your data objects:

<bean id="myDaoFactory" class="mypackage.factory.myDaoFactoryImpl"
  factory-method="getFactory" scope="singleton"/>

Autowiring
Use the Autowired annotation to automatically add beans to your consuming classes.

/**
* Storage engine.
*/
@Autowired
private Storage storage;

Non-SQL databases
Non-SQL databases should be handled through high level “use case” calls against a storage engine rather than direct puts and gets.

3 Responses to “Notes on Spring development”

  1. Shih-gian Lee Says:

    In the interface-oriented design, you have myDaoFactoryImpl. Why do you use a factory on boundary classes?

  2. Chris Says:

    I didn’t view the DAO as a boundary class, rather a resource or object that needed to be properly instantiated within the application. The DAO provides business rule implementations rather than low level generic access to the database. Additionally, I wanted to emphasize interface/factory as a common pattern throughout the system, in part to integrate well with Spring but also to make development and future maintenance consistent.

  3. Shih-gian Lee Says:

    Isn’t it violated the use of Dao with business logic in it?

    A proper use interface-oriented design can be done at the business service layer. The “application” business logic can reside in the business service layer where transaction is managed. This is a common practice in Spring and will achieve what you need.

Leave a Reply