spring AOP 拦截日志

  • Post author:
  • Post category:其他


1   首先引入jar包

spring.jar  aopalliance.jar  aspectjrt.jar  aspectjtools.jar  aspectjweaver.jar  cglib-nodep-2.1_3.jar  cglib-src-2.2.jar    这些个jar包不一定都用得上,但离配置到现在整理已经比较久了  有点忘了.

2  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



xmlns:aop=”

http://www.springframework.org/schema/aop



xmlns:tx=”

http://www.springframework.org/schema/tx



xmlns:jee=”

http://www.springframework.org/schema/jee



xsi:schemaLocation=”

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans-2.0.xsd



http://www.springframework.org/schema/aop


http://www.springframework.org/schema/aop/spring-aop-2.0.xsd



http://www.springframework.org/schema/tx


http://www.springframework.org/schema/tx/spring-tx-2.0.xsd



http://www.springframework.org/schema/jee


http://www.springframework.org/schema/jee/spring-jee-2.0.xsd

“>

3   定义 aop拦截

<aop:aspectj-autoproxy proxy-target-class=”true” />

<aop:config proxy-target-class=”true”>

<aop:aspect ref=”logMonitor”>

<aop:pointcut id=”actionPointcut” expression=”execution(* com.*.*.*.service.impl.*.create*(..)) || execution(* com.*.*.*.service.impl.*.update*(..)) || execution(* com.*.*.*.service.impl.*.delete*(..))|| execution(* com.*.*.*.service.impl.*.insert*(..))||execution(* com.*.*.service.impl.*.create*(..)) || execution(* com.*.*.service.impl.*.update*(..)) || execution(* com.*.*.service.impl.*.delete*(..))|| execution(* com.*.*.service.impl.*.insert*(..))”/>

<aop:before pointcut-ref=”actionPointcut” method=”writeLogInfo” />

</aop:aspect>

</aop:config>

<bean id=”logMonitor” parent=”baseTransactionProxy”>

<property name=”target”>

<bean

class=”com.*.common.userlog.monitor.LogMonitor”>

<property name=”userLogInfoService”>

<ref bean=”userLogInfoService” />

</property>

</bean>

</property>

</bean>

4  处理拦截的类logMonitor

@Aspect

public class LogMonitor {

/** * 保存变量的ThreadLocal,保持在同一线程中同步数据. */

private static final ThreadLocal SESSION_MAP = new ThreadLocal();

private IUserLogInfoService userLogInfoService;

public IUserLogInfoService getUserLogInfoService() {


return userLogInfoService;

}

public void setUserLogInfoService(IUserLogInfoService userLogInfoService) {


this.userLogInfoService = userLogInfoService;

}

/**

* 获得线程中保存的属性.

*

* @param attribute

*            属性名称

* @return 属性值

*/

public static Object get(String attribute) {


Map map = (Map) SESSION_MAP.get();

return map.get(attribute);

}

/**

* 记录日志信息

* @param joinpoint

* @throws Exception

* @throws IllegalAccessException

*/

public void writeLogInfo(JoinPoint joinpoint) throws Exception, IllegalAccessException {

UserInfoVO sysUse = (UserInfoVO) UserSession.get(Contents.SESSION_USER_KEY);

//  在基类action中 设用户信息

// UserSession.set(Contents.SESSION_USER_KEY, userVO);

// UserSession.set(Contents.SESSION_USER_IP, request.getRemoteAddr());


String userIP = (String) UserSession.get(Contents.SESSION_USER_IP);

String temp = joinpoint.getStaticPart().toShortString();

// 获得操作类

String classType = joinpoint.getTarget().getClass().getName();

// 获得方法名称

String methodName = temp.substring(10, temp.length() – 1);

Class className = Class.forName(classType);

// 获得方法的参数类型数组

Object[] a = joinpoint.getArgs();

Class[] o = new Class[a.length];//

for (int i = 0; i < a.length; i++) {


o[i] = a[i].getClass();

}

Method method = className.getMethod(methodName, o);

LogDesc desc = method.getAnnotation(LogDesc.class);

// 获得方法的操作动作类型说明

String actionDesc = “”;

if (desc != null) {


actionDesc = desc.actionDesc();

}

// 记录日志信息

UserLogInfo userLogInfo = new UserLogInfo();

if (sysUse != null) {


userLogInfo.setUserID(sysUse.getUserID());

userLogInfo.setUserIp(userIP);

userLogInfo.setOperateClass(classType);

userLogInfo.setOperateMethod(methodName);

//设置为一般日志信息标识位

userLogInfo.setEnableFlag(“C”);

userLogInfo.setOperateDescribe(actionDesc);

}

userLogInfoService.addUserLog(userLogInfo);

}

5   定义取得拦截方法描述的类

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface LogDesc {


String actionDesc();

}

6  在每个需要拦截的方法头加上

/**

* 注册新用户

*

* @roseuid 3C30BD930399

*/

@LogDesc(actionDesc = “新建会员”)

public MemberVO createMember(MemberVO memberVO) throws SysComException {


return memberRegisterDao.createMember(memberVO);

}

7    设置、取得用户信息

public class UserSession{


// private static ThreadLocal<Object> threadLocal = new ThreadLocal<Object>();

//

// public  HttpServletRequest getContext(){

// return (HttpServletRequest)threadLocal.get();

// }

// public  void setContext(HttpServletRequest request){

// threadLocal.set(request);

// }

//

// public void cleanContext(){

// threadLocal.set(null);

// }

/** * 保存变量的ThreadLocal,保持在同一线程中同步数据. */

private static final ThreadLocal SESSION_MAP = new ThreadLocal();

/** * 工具类的protected构造方法. */

protected UserSession() {

}

/**

* 获得线程中保存的属性.

*

* @param attribute

*            属性名称

* @return 属性值

*/

public static Object get(String attribute) {

Map map = (Map) SESSION_MAP.get();

//System.out.println(map.toString());

// System.out.println(map.containsKey(“usersession”));

return map.get(attribute);

}

/**

* 获得线程中保存的属性,使用指定类型进行转型.

*

* @param attribute

*            属性名称

* @param clazz

*            类型

* @param <T>

*            自动转型

* @return 属性值

*/

public static <T> T get(String attribute, Class<T> clazz) {

return (T) get(attribute);

}

/**

* 设置制定属性名的值.

*

* @param attribute

*            属性名称

* @param value

*            属性值

*/

public static void set(String attribute, Object value) {

Map map = (Map) SESSION_MAP.get();

if (map == null) {

map = new HashMap();

SESSION_MAP.set(map);

}

map.put(attribute, value);

}

8  另外在配置aop必须是接口的, 否则会出错

看是否可以在action设置拦截效果应该更好的。