spring AOP 拦截日志
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-/>
?? <aop:config proxy-target-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
?????/>
?????</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设置拦截效果应该更好的。