Spring中添加 Log4j注解
package cn.com.vnvtrip.spring.log4j.ext;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.Collections;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanInitializationException;import org.springframework.beans.factory.config.BeanPostProcessor;import cn.com.vnvtrip.spring.log4j.anonation.Logger;/** * Log4j日志注解化的应用 基本原理如下: * 通过自定义一个BeanPostProcessor, 在对所有bean初始化之前, * 对每一个bean的field进行检查, 是否适用了Logger注解, 如果有, 则调用LogFactory创建一个logger实例. * * @author longgangbai * */public class LogBeanPostProcessor implements BeanPostProcessor { /** * 初始化之后的操作 */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * 初始化之前的操作的处理 */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { List<Class<?>> clazzes = getAllClasses(bean); for (Class<?> clazz : clazzes) { initializeLog(bean, clazz); } return bean; } /** * 初始化添加日志功能的 * * @param bean * @param clazz */ private void initializeLog(Object bean, Class<? extends Object> clazz) { Field[] fiels = clazz.getDeclaredFields(); for (Field field : fiels) { if (field.getAnnotation(Logger.class) == null) { continue; } if (!field.getType().isAssignableFrom(Log.class)) { continue; } // 取是否可以方法的属性 boolean visable = field.isAccessible(); try { // 置可以属性为可以访问 field.setAccessible(true); field.set(bean, LogFactory.getLog(clazz)); } catch (Exception e) { throw new BeanInitializationException(String.format( "初始化logger失败!bean=%s;field=%s", bean, field)); } finally { // 恢复原来的访问修饰 field.setAccessible(visable); } } } /** * * 取制定bean的class以及所有父类的列表,该列表中顺序为从父类中当前类 * * @param bean * @return */ private List<Class<?>> getAllClasses(Object bean) { Class<? extends Object> clazz = bean.getClass(); List<Class<?>> clazzes = new ArrayList<Class<?>>(); while (clazz != null) { clazzes.add(clazz); clazz = clazz.getSuperclass(); } Collections.reverse(clazzes); return clazzes; }}置注解类package cn.com.vnvtrip.spring.log4j.anonation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 添加一日志注解类 * * @author longgangbai * */@Retention(RetentionPolicy.RUNTIME) //运行是编译@Target( { ElementType.FIELD }) //修饰的字段public @interface Logger {}package cn.com.vnvtrip.spring.log4j.test;import org.apache.commons.logging.Log;import cn.com.vnvtrip.spring.log4j.anonation.Logger;public class LoggAnonation { @Logger private static Log log; public double divide(int a, int b) { if (b == 0) { log.error("被除数不可以为0"); } else { return a / b; } return -1; }}Spring配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="logBeanPocessor" /> <bean id="loganonation" class="cn.com.vnvtrip.spring.log4j.test.LoggAnonation"/></beans> 测试类:package cn.com.vnvtrip.spring.log4j.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class LogTest { public static void main(String[] args) { ApplicationContext ctxapp = new ClassPathXmlApplicationContext( "applicationContext.xml"); LoggAnonation logtest = (LoggAnonation) ctxapp.getBean("loganonation"); double a = logtest.divide(8, 0); System.out.println(a); }}
?