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.

September 6th, 2009 at 4:09 pm
In the interface-oriented design, you have myDaoFactoryImpl. Why do you use a factory on boundary classes?
September 6th, 2009 at 4:26 pm
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.
September 7th, 2009 at 6:50 am
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.