Spring AOP for writing to the event log function

 

What is AOP? AOP usage scenarios? AOP concepts? Spring AOP components? How to use Spring AOP? Etc. These questions refer to the blog: the Spring AOP implementation principle

Here we focus on how to write event log function, to save the log to the database. 
The event log is not related to the main business logic function, implemented with AOP is no better, and because of which some field parameters database log table needs to be passed, it will use custom annotations, these parameters will be passed over with a custom annotation .

1. custom annotation Operation

package com.jykj.demo.filter;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Descrption该注解描述方法的操作类型和方法的参数意义 */ @Target(value = ElementType.METHOD) @Retention(value = RetentionPolicy.RUNTIME) @Documented public @interface Operation { /** * @Description描述操作类型 为必填项,1:登录日志2:操作日志 */ int type(); /** * @Description描述操作意义 比如申报通过或者不通过等 */ String desc() default ""; /** * @Description描述操作方法的参数意义 数组长度需与参数长度一致,否则会参数与描述不一致的情况 */ String[] arguDesc() default {}; } 

 

2. cut class EventLogAspect

package com.jykj.demo.filter; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import com.jykj.demo.service.SysEventService; //事件日志 切面,凡是带有 @Operation 注解的service方法都将会写日志 public class EventLogAspect { @Autowired SysEventService sysEventService; public void doAfterReturning(JoinPoint jp) { System.out.println( "log Ending method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); Method proxyMethod = ((MethodSignature) jp.getSignature()).getMethod(); Method soruceMethod; try { soruceMethod = jp.getTarget().getClass().getMethod(proxyMethod.getName(), proxyMethod.getParameterTypes()); Operation oper = soruceMethod.getAnnotation(Operation.class); if (oper != null) { System.out.println(oper.desc()); // 解析参数 sysEventService.insertEventLog(oper.type(),oper.desc()+"("+extractParam(jp.getArgs(),oper.arguDesc())+") 成功"); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); }catch (Exception e) { e.printStackTrace(); } } public void doAfterThrowing(JoinPoint jp, Throwable ex) { Method proxyMethod = ((MethodSignature) jp.getSignature()).getMethod(); Method soruceMethod; try { soruceMethod = jp.getTarget().getClass().getMethod(proxyMethod.getName(), proxyMethod.getParameterTypes()); Operation oper = soruceMethod.getAnnotation(Operation.class); if (oper != null) { System.out.println(oper.desc()); sysEventService.insertEventLog(oper.type(),oper.desc()+ "("+extractParam(jp.getArgs(),oper.arguDesc())+" 出现异常:"+ex.getMessage()); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } private String extractParam(Object[] objParam, String[] arguDesc) { StringBuilder sb = new StringBuilder(); int len = objParam.length<arguDesc.length?objParam.length:arguDesc.length;//取最小值 for (int i = 0; i < len; i++) { //空字符串将不解析 if(arguDesc[i]!=null && !arguDesc[i].isEmpty()){ sb.append(arguDesc[i]+":"+objParam[i]+","); } } String rs = sb.toString(); return rs.substring(0,rs.length()-1); } } 

 

3. The entry point of the main business logic classes FrmAppsService

package com.jykj.demo.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.jykj.demo.dao.FrmAppsMapper; import com.jykj.demo.entity.FrmApps; import com.jykj.demo.filter.Operation; import com.jykj.demo.mapper.AbstractService; @Service public class FrmAppsService { @Autowired FrmAppsMapper mapper; @Operation(type=1,desc="更新框架应用",arguDesc={"","操作类型"}) public int access(FrmApps app,String action){ return mapper.access(app,action); } }

 

4.Spring xml configuration of AOP

    <bean id="aspectEventLog" class="com.jykj.demo.filter.EventLogAspect" /> <!-- <aop:aspectj-autoproxy /> --> <!--配置service包下所有类或接口的所有方法--> <aop:config proxy-target-class="true"> <aop:aspect id="EventLogAspect" ref="aspectEventLog"> <aop:pointcut id="myService" expression="execution(* com.jykj.demo.service.*.*(..)) " /> <aop:after-returning pointcut-ref="myService" method="doAfterReturning"/> <aop:after-throwing pointcut-ref="myService" method="doAfterThrowing" throwing="ex"/> </aop:aspect> </aop:config> <!-- 控制器 --> <context:component-scan base-package="com.jykj.demo.controller" /> <!-- service --> <context:component-scan base-package="com.jykj.demo.service" /> <context:component-scan base-package="com.jykj.demo.filter" />

 

Note that the proxy-target-class = "true", if not this, if the target class implements the interface, the agent will be in JDK way, otherwise it uses a proxy CGLib the way, if you start the project being given, will be reported Acting classes can not be converted problem, this time to write this configuration on it.

This realization of the write log feature, custom annotation Operation notes can be used as long as the method of service classes need to write log

5. Output (editing a record)

log Ending method: com.jykj.demo.service.FrmAppsService.access
更新框架应用
log Ending method: com.jykj.demo.service.SysEventService.insertEventLog

 

Write pictures described here

Additional disable access to an additional page address is not the function of the use of interceptors 
SecurityInterceptor class

package com.jykj.demo.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import com.jykj.demo.util.Helper; public class SecurityInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); if (session.getAttribute(Helper.SESSION_USER) == null) { throw new AuthorizationException(); } else { return true; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub } } 

 

Corresponding interceptor arranged spring-mvc.xml

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/*"/> <mvc:exclude-mapping path="/login"/> <mvc:exclude-mapping path="/signIn"/> <mvc:exclude-mapping path="/register"/> <bean class="com.jykj.demo.filter.SecurityInterceptor"> </bean> </mvc:interceptor> </mvc:interceptors> <!-- bean 处理未登录重定向到登录界面 --> <bean id="handlerExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="com.jykj.demo.filter.AuthorizationException">redirect:login</prop> </props> </property> </bean>

 

 

Exception class AuthorizationException

package com.jykj.demo.filter;

public class AuthorizationException extends Exception{ private static final long serialVersionUID = 1L; } 

Guess you like

Origin www.cnblogs.com/liuxiaofu/p/12005083.html