Today I continue to implement AOP. I personally think it is the most flexible and extensible way. Take log management as an example, using Spring AOP custom annotation form to implement log management. Without further ado, start right away! ! !
I'll say again about configuration.
What to add in applicationContext-mvc.xml
<mvc:annotation-driven /><!-- Activate component scanning function, automatically scan components configured through annotation under package com.gcx and its subpackages --><context:component-scan base-package="com.gcx" /> <!-- Start support for @AspectJ annotation --> <!-- proxy-target-class equals true, which forces the use of cglib proxy. proxy-target-class is false by default. If your class implements the interface, go to JDK proxy. If not, go to cglib proxy--><!-- Note: It is recommended to use cglib proxy for the simple profit mode. Although JDK dynamic proxy is faster than cglib proxy, its performance is not as good as cglib --><!--If you don't write proxy-target-class="true" the sentence is OK --><aop:aspectj-autopproxy proxy-target-class="true"/> <!--Section--><bean id="systemLogAspect"></bean>
Next, start writing the code.
Create a log entity
public class SystemLog { private String id; private String description; private String method; private Long logType; private String requestIp; private String exceptioncode; private String exceptionDetail; private String params; private String createBy; private Date createDate; public String getId() { return id; } public void setId(String id) { this.id = id == null ? null : id.trim(); } public String getDescription() { return description; } public void setDescription(String description) { this.description = description == null ? null : description.trim(); } public String getMethod() { return method; } public void setMethod(String method) { this.method = method == null ? null : method.trim(); } public Long getLogType() { return logType; } public void setLogType(Long logType) { this.logType = logType; } public String getRequestIp() { return requestIp; } public void setRequestIp(String requestIp) { this.requestIp = requestIp == null ? null : requestIp.trim(); } public String getExceptioncode() { return exceptioncode; } public void setExceptioncode(String exceptioncode) { this.exceptioncode = exceptioncode == null ? null : exceptioncode.trim(); } public String getExceptionDetail() { return exceptionDetail; } public void setExceptionDetail(String exceptionDetail) { this.exceptionDetail = exceptionDetail == null ? null : exceptionDetail.trim(); } public String getParams() { return params; } public void setParams(String params) { this.params = params == null ? null : params.trim(); } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy == null ? null : createBy.trim(); } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; }}Writing a dao interface
package com.gcx.dao;import com.gcx.entity.SystemLog;public interface SystemLogMapper { int deleteByPrimaryKey(String id); int insert(SystemLog record); int insertSelective(SystemLog record); SystemLog selectByPrimaryKey(String id); int updateByPrimaryKey(SystemLog record);}Writing a service layer
package com.gcx.service;import com.gcx.entity.SystemLog;public interface SystemLogService { int deleteSystemLog(String id); int insert(SystemLog record); int insertTest(SystemLog record); SystemLog selectSystemLog(String id); int updateSystemLog(SystemLog record);}Write service implementation class serviceImpl
package com.gcx.service.impl;import javax.annotation.Resource;import org.springframework.stereotype.Service;import com.gcx.annotation.Log;import com.gcx.dao.SystemLogMapper;import com.gcx.entity.SystemLog;import com.gcx.service.SystemLogService;@Service("systemLogService")public class SystemLogServiceImpl implements SystemLogService { @Resource private SystemLogMapper systemLogMapper; @Override public int deleteSystemLog(String id) { return systemLogMapper.deleteByPrimaryKey(id); } @Override public int insert(SystemLog record) { return systemLogMapper.insertSelective(record); } @Override public SystemLog selectSystemLog(String id) { return systemLogMapper.selectByPrimaryKey(id); } @Override public int updateSystemLog(SystemLog record) { return systemLogMapper.updateByPrimaryKeySelective(record); } @Override public int insertTest(SystemLog record) { return systemLogMapper.insert(record); }}Here the basic program is finished
Below is the custom annotation
package com.gcx.annotation;import java.lang.annotation.*;@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log { /** The type of operation to be performed, such as: add operation**/ public String operationType() default ""; /** The specific operation to be performed, such as: add user**/ public String operationName() default "";}Write the cut below
package com.gcx.annotation;import java.lang.reflect.Method;import java.util.Date;import java.util.UUID;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import com.gcx.entity.SystemLog;import com.gcx.entity.User;import com.gcx.service.SystemLogService;import com.gcx.util.JsonUtil;/** * @author Yang Jian* @E-mail: email * @version Created time: 2015-10-19 4:29:05 pm * @desc Point-cut class*/@Aspect@Componentpublic class SystemLogAspect { //Inject Service to save logs to the database @Resource //I use resource annotation here, generally using @Autowired. Their differences. If I have time, I will write private SystemLogService systemLogService in the subsequent blog; private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class); //Controller layer tangent point @Pointcut("execution (* com.gcx.controller..*.*(..))") public void controllerAspect() { } /** * Pre-notification is used to intercept the Controller layer to record the user's operations* * @param joinPoint point tangent point*/ @Before("controllerAspect()") public void doBefore(JoinPoint joinPoint) { System.out.println("===================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== System.out.println("========================================================================================== System.currentTimeMillis(); try { ((ProceedingJoinPoint) joinPoint).proceed(); long end = System.currentTimeMillis(); if(logger.isInfoEnabled()){ logger.info("around " + joinPoint + "/tUse time : " + (end - start) + " ms!"); } System.out.println("============================================================================ System.currentTimeMillis(); if(logger.isInfoEnabled()){ logger.info("around " + joinPoint + "/tUse time : " + (end - start) + " ms with exception : " + e.getMessage()); } } } /** * Post notification is used to intercept the controller layer to record the user's operations* * @param joinPoint tangent point*/ @After("controllerAspect()") public void after(JoinPoint joinPoint) { /* HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession session = request.getSession(); */ // Read the user in the session// User user = (User) session.getAttribute("user"); // Requested IP //String ip = request.getRemoteAddr(); User user = new User(); user.setId(1); user.setName("Zhang San"); String ip = "127.0.0.1"; try { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); String operationType = ""; String operationName = ""; for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] clazzs = method.getParameterTypes(); if (clazzs.length == arguments.length) { operationType = method.getAnnotation(Log.class).operationType(); operationName = method.getAnnotation(Log.class).operationName(); break; } } } //*===================*// System.out.println("========== Controller post notification start==========); System.out.println("Request method:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); System.out.println("Method Description:" + operationName); System.out.println("Requester:" + user.getName()); System.out.println("Request IP:" + ip); //*====================*// SystemLog log = new SystemLog(); log.setId(UUID.randomUUID().toString()); log.setDescription(operationName); log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); log.setLogType((long)0); log.setRequestIp(ip); log.setExceptioncode(null); log.setExceptionDetail(null); log.setParams(null); log.setCreateBy(user.getName()); log.setCreateDate(new Date()); //Save the database systemLogService.insert(log); System.out.println("=========== Controller post-notification end=========="); } catch (Exception e) { //Record local exception log logger.error("==Post-notification exception=="); logger.error("Exception information:{}", e.getMessage()); } } //Configure post-return notifications, use the entry point registered on method aspect() @AfterReturning("controllerAspect()") public void afterReturn(JoinPoint joinPoint){ System.out.println("====== Execute controller post-return notification========); if(logger.isInfoEnabled()){ logger.info("afterReturn " + joinPoint); } } /** * Exception notification is used to intercept the log of exception * * @param joinPoint * @param e */ @AfterThrowing(pointcut = "controllerAspect()", throwing="e") public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { /*HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession session = request.getSession(); //Read the user in the session User user = (User) session.getAttribute(WebConstants.CURRENT_USER); //Get request ip String ip = request.getRemoteAddr(); */ //Get the parameters of the user request method and serialize it into JSON format string User user = new User(); user.setId(1); user.setName("Zhang San"); String ip = "127.0.0.1"; String params = ""; if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) { for ( int i = 0; i < joinPoint.getArgs().length; i++) { params += JsonUtil.getJsonStr(joinPoint.getArgs()[i]) + ";"; } } try { String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class targetClass = Class.forName(targetName); Method[] methods = targetClass.getMethods(); String operationType = ""; String operationName = ""; for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] clazzs = method.getParameterTypes(); if (clazzs.length == arguments.length) { operationType = method.getAnnotation(Log.class).operationType(); operationName = method.getAnnotation(Log.class).operationName(); break; } } } /*==============Console output========*/ System.out.println("================Exception notification start============================================================================================================================================================================================================================================================================================================================================================================== System.out.println("Exception information:" + e.getMessage()); System.out.println("Exception method:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); System.out.println("Method description:" + operationName); System.out.println("Requester:" + user.getName()); System.out.println("Request IP:" + ip); System.out.println("Request Parameters:" + params); /*=================== Database log==========*/ SystemLog log = new SystemLog(); log.setId(UUID.randomUUID().toString()); log.setDescription(operationName); log.setExceptioncode(e.getClass().getName()); log.setLogType((long)1); log.setExceptionDetail(e.getMessage()); log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")); log.setParams(params); log.setCreateBy(user.getName()); log.setCreateDate(new Date()); log.setRequestIp(ip); //Save the database systemLogService.insert(log); System.out.println("========Exception notification end=========================; } catch (Exception ex) { //Record local exception logger.error("==Exception notification exception=="); logger.error("Exception information:{}", ex.getMessage()); } /*========================*/ logger.error("Exception method:{}Exception code:{}Exception information:{} Parameters:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getClass().getName(), params); } }I have written a lot here, including pre-notice, surround notification, post-notice, exception notification, and post-meal notification. It's okay if I don't write it all in our actual writing. I'm used to writing the logic of logging in the post-log. I see that some of the pre-log notifications are also included in the pre-log notifications on the Internet, but I feel that it's better to write it in the post-log notifications.
Let’s start adding custom annotations to the controller! !
package com.gcx.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.gcx.annotation.Log;import com.gcx.service.UserService;@Controller@RequestMapping("userController")public class UserController { @Autowired private UserService userService; @RequestMapping("testAOP") @Log(operationType="add operation:",operationName="Add user") public void testAOP(String userName,String password){ userService.addUser(userName, password); }}Write the test class below
@Test public void testAOP1(){ //Start Spring container ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext-mvc.xml","classpath:applicationContext-dataSource.xml"}); //Get service or controller component UserController userController = (UserController) ctx.getBean("userController"); userController.testAOP("zhangsan", "123456"); }Database data:
I originally wanted to write two tangent points, one is the service layer and the other is the controller layer. The service layer is used to record exception information, while the controller layer is used to record functions. The running result is as follows.
If you do this, I don’t know if the operation efficiency is good in the actual project. Please see the blog’s Daniu here to give some suggestions! !
The above example explanation of spring AOP custom annotation method to implement log management is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.