Requirement background
In a recent project, when the project is basically completed, the customer proposed to record the logs of all business operations into the database and extract some key business information (such as transaction order numbers) in the log.
In order to ensure the construction period, after reviewing the information, I decided to use AOP + custom annotations to complete this requirement.
Preparation
The jar packages that need to be depended on for custom annotations include aspectjrt-XXX.jar, aspectjweaver-XXX.jar, and XXX represents the version number.
Custom annotations
A separate log package is created under the project to store log-related content
**.common.log.annotation //Custom annotation storage location **.common.log.aop //Aop tool storage location
Create a new custom annotation class under the annotation package:
package **.common.log.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)public @interface XXXOperateLog { /** * Operation type description* @return */ String operateTypeDesc() default ""; /** * Operation type* @return */ long operateType() default -1; /** * Module encoding* @return */ String mouseCode() default "M30"; /** * Module name* @return */ String mouseName() default "XX module"; /** * Business type* @return */ String bussType() default ""; /** * Business type description* @return */ String bussTypeDesc() default "";}Create a new XXXOperateLogAop under the aop package
package **.common.log.aop;import ** ;//Omit @Aspect@Componentpublic class XXXOperateLogAop{ @Autowired SystemLogService systemLogService; HttpServletRequest request = null; Logger logger = LoggerFactory.getLogger(XXXOperateLogAop.class); ThreadLocal<Long> time = new ThreadLocal<Long>(); //Unique ID used to generate operation logs, used to call public static for business process audit logs ThreadLocal<String> tag = new ThreadLocal<String>(); //Declare the AOP entry point, any method that uses XXXOperateLog is intercepted @Pointcut("@annotation(**.common.log.annotation.XXXOperateLog)") public void log() { System.out.println("I am a entry point"); } /** * Cut in all places marked @Log* @param joinPoint */ @Before("log()") public void beforeExec(JoinPoint joinPoint) { time.set(System.currentTimeMillis()); info(joinPoint); //Set the unique identification number of log records tag.set(UUID.randomUUID().toString()); request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } @After("log()") public void afterExec(JoinPoint joinPoint) { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); logger.debug("Tag as "+ tag.get() + "Method" + method.getName() + "Run consumption" + (System.currentTimeMillis() - time.get()) + "ms"); } //In the process of executing the target method, this method will be executed, and logging can be implemented here @Around("log()") public Object aroundExec(ProceedingJoinPoint pjp) throws Throwable { Object ret = pjp.proceed(); try { Object[] orgs = pjp.getArgs(); SystemLog valueReturn = null; for (int i = 0; i < orgs.length; i++) { if(orgs[i] instanceof SystemLog){ valueReturn = (SystemLog) orgs[i]; } } if(valueReturn==null){ valueReturn = new SystemLog(); } if(valueReturn!=null&&request!=null){ MethodSignature ms = (MethodSignature) pjp.getSignature(); Method method = ms.getMethod(); //Get the operation log information of the annotation XXXOperateLog log = method.getAnnotation(XXXOperateLog.class); String businessType = log.bussType(); String businessDesc = log.bussTypeDesc(); HashMap requestMap = ServletUtils.getParametersToHashMap(request); //Look for business type from parameters if(businessType.equals("")) { Object objBusinessType = requestMap.get("business_type"); businessType = objBusinessType == null ? "" : objBusinessType.toString(); } //Found the business type from the application form for the execution result. Object apply = request.getAttribute("apply") ; if(apply != null){ JSONObject obj = JSONFactory.toJSONAbstractEntity(apply); if(obj != null) { valueReturn.setOtherDesc("Apply number:"+obj.getString("apply_no")); if(businessType.equals("")) { businessType = obj.getString("business_type"); } } } //Finding the business type from the execution process parameters of the method (usually manually set) if(businessType.equals("")) { businessType = (String) request.getAttribute("business_type"); businessType = businessType == null ? "" : businessType; } if(!businessType.equals("") && businessDesc.equals("")) { businessDesc = XXXSysConstant.BUSINESS_TYPE.getName(businessType); } valueReturn.setBussType(XXXSysConstant.BUSINESS_TYPE.getNumber(businessType)); valueReturn.setBussTypeDesc(businessDesc); valueReturn.setMoudleCode(log.moudleCode()); valueReturn.setMoudleName(log.moudleName()); valueReturn.setOperateResult(XXXSysConstant.YesOrNo.YES); valueReturn.setOperateType(log.operateType()); valueReturn.setInputUserId(((UserContext)WebUtils.getSessionAttribute(request, "XXXuserContext")).getSysUser().getId()); valueReturn.setOperateTypeDesc(log.operateTypeDesc()); valueReturn.setRequestIp(getRemoteHost(request)); valueReturn.setRequestUrl(request.getRequestURI()); valueReturn.setServerIp(request.getLocalAddr()); valueReturn.setUids(tag.get()); //Save the operation log systemLogService.saveSystemLog(valueReturn); }else{ logger.info("Do not record log information"); } //Save the operation result} catch (Exception e) { e.printStackTrace(); } return return; } //Record exception log @AfterThrowing(pointcut = "log()", throwing="e") public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { try { info(joinPoint); Object[] orgs = joinPoint.getArgs(); SystemLog valueReturn = null; for (int i = 0; i < orgs.length; i++) { if(orgs[i] instanceof SystemLog){ valueReturn = (SystemLog) orgs[i]; } } if(valueReturn==null){ valueReturn = new SystemLog(); } if(valueReturn!=null&&request!=null){ MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); XXXOperateLog log = method.getAnnotation(XXXOperateLog.class); String businessType = log.bussType(); String businessDesc = log.bussTypeDesc(); if(businessType.equals("")) { Object objBusinessType = ServletUtils.getParametersToHashMap(request).get("business_type"); businessType = objBusinessType == null ? "" : objBusinessType.toString(); businessDesc = XXXSysConstant.BUSINESS_TYPE.getName(businessType); } valueReturn.setBussType(XXXSysConstant.BUSINESS_TYPE.getNumber(businessType)); valueReturn.setBussTypeDesc(businessDesc); valueReturn.setMoudleCode(log.moudleCode()); valueReturn.setMoudleName(log.moudleName()); valueReturn.setOperateType(log.operateType()); valueReturn.setOperateTypeDesc(log.operateTypeDesc()); valueReturn.setInputUserId(((UserContext)WebUtils.getSessionAttribute(request, "XXXuserContext")).getSysUser().getId()); valueReturn.setOperateResult(XXXSysConstant.YesOrNo.NO); String errMes = e.getMessage(); if(errMes!=null && errMes.length()>800){ errMes = errMes.substring(0, 800); } valueReturn.setErrorMessage(errMes); valueReturn.setRequestIp(getRemoteHost(request)); valueReturn.setRequestUrl(request.getRequestURI()); valueReturn.setServerIp(request.getLocalAddr()); valueReturn.setUids(tag.get()); systemLogService.saveSystemLog(valueReturn); }else{ logger.info("No log information is recorded"); } } catch (Exception e1) { e1.printStackTrace(); } } private void info(JoinPoint joinPoint) { logger.debug("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Object[] os = joinPoint.getArgs(); logger.debug("Args:"); for (int i = 0; i < os.length; i++) { logger.debug("/t==>parameter[" + i + "]:/t" + os[i].toString()); } logger.debug("Signature:/t" + joinPoint.getSignature()); logger.debug("SourceLocation:/t" + joinPoint.getSourceLocation()); logger.debug("StaticPart:/t" + joinPoint.getStaticPart()); logger.debug("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- request.getHeader("Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){ ip = request.getHeader("WL-Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){ ip = request.getRemoteAddr(); } return ip.equals("0:0:0:0:0:0:0:0:0:0:0:0:1")?"127.0.0.1":ip; } }Modify the configuration file spring-mvc.xml and add the following configuration
<!-- Turn on AOP interception--> <aop:aspectj-autoproxy proxy-target-class="true" /> <mvc:annotation-driven /> <!-- Define the scope of Spring description Bean--> <context:component-scan base-package="**.common.log" > <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
It should be noted that the above configuration must be placed in the same xml file, either spring-mvc.xml or spring-context.xml, otherwise it may not take effect, and the reason has not been found yet.
Use of annotations
@XXXOperateLog( bussType=XXXSysConstant.BUSINESS_TYPE.YYYY,bussTypeDesc="Business Type Description" ,operateType = XXXSysConstant.LogOperateType.QUERY,operateTypeDesc = "Operation Description" ) @RequestMapping(value = "/**/**/queryXXXX4DataGrid.json", method = RequestMethod.POST) public void queryXXXXX4DataGrid(HttpServletRequest request, HttpServletResponse arg1, Model model, Writer writer) { logger.info("============================================================================================= HttpServletResponse arg1, Model model, Writer writer) { logger.info("=============================== HttpServletResponse arg1, Model model, Writer writer) { logger.info("========================= HttpServletResponse arg1, Model model, Writer writer) { logger.info("==================== HttpServletResponse arg1, Model model, Writer writer) { logger.info("=================== HttpServletResponse arg1, Model model, Writer writer) { logger.info("================== HttpServletResponse arg1, Model model, Writer writer) { logger.info("=================== HttpServletResponse arg1, Model model, Writer writer) { logger.info("==================== HttpServletResponse arg1, Model model,The above springMVC custom annotation, the method of using AOP to realize logging 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.