`

spring+aop+自定义注解实现操作日志记录

    博客分类:
  • java
 
阅读更多

1,spring配置文件

<bean class="com.able.aop.LogAspect" id="logAspect"/>

    <aop:config>
        <aop:aspect id="serviceMonitor" ref="logAspect">
            <aop:pointcut expression="execution(* com.able.controller.*.*(..))" id="servicePointcut" />
            <aop:around method="doAroundMethodLog" pointcut-ref="servicePointcut"/>
        </aop:aspect>
    </aop:config>

 

2,日志拦截类

public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserOperatLogService userOperatLogService;
    @Autowired
    private TokenService tokenService;
    /**
     * 标注该方法体为环绕通知,当目标方法执行时执行该方法体
     */
    public Object doAroundMethodLog(ProceedingJoinPoint jp) throws Throwable{
        StopWatch stopWatch = new StopWatch(); //记录方法执行耗时
        stopWatch.start();
        Object retVal = null;
        try{
            retVal = jp.proceed();
        }catch (Throwable e){
            e.printStackTrace();
            logger.error(e.getMessage());
            retVal = new ResponseEntity(new RestResult(e.getMessage(),false), HttpStatus.OK);
        }finally {
            stopWatch.stop();
            insertOpertLog(jp, stopWatch);
        }
        return retVal;
    }
	private void insertOpertLog(ProceedingJoinPoint jp, StopWatch stopWatch) {
		Class<? extends Object> classD=jp.getTarget().getClass();
		String className = classD.getName();
		MethodSignature joinPointObject = (MethodSignature) jp.getSignature();
		Method method = joinPointObject.getMethod();
		String methodName = method.getName();
		if(!jp.getTarget().getClass().isAnnotationPresent(NoLog.class)&&!method.isAnnotationPresent(NoLog.class)){
			String params = parseParames(jp.getArgs()); //解析目标方法体的参数
			UserOperatLog userOperatLog=new UserOperatLog();
			userOperatLog.setIpAddr(request.getRemoteAddr());
			userOperatLog.setActionUrl(request.getRequestURI());
			userOperatLog.setTimeLong(stopWatch.getTotalTimeMillis()+"");
			ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			if(shiroUser!=null){
				userOperatLog.setUserId(shiroUser.getZhsId());
				userOperatLog.setUserName(shiroUser.getRealName());
			}else{
				String tokenCode=request.getParameter("tokenCode")==null?"":request.getParameter("tokenCode");
				if(tokenCode!=null && !"".equals(tokenCode)){
					Token token = new Token();
					token.setTokenCode(tokenCode);
					List<Token> list =tokenService.selectBySelective(token);
					if(list != null && list.size() > 0){
						token=list.get(0);
						userOperatLog.setUserId(token.getUserId());
						userOperatLog.setUserName(token.getRealName());
					}
				}
			}
			Function fd = null;
			Operate md = null;
			if(classD.isAnnotationPresent(Function.class)){
			    fd = classD.getAnnotation(Function.class);
			}
			if(method.isAnnotationPresent(Operate.class)){
			    md =method.getAnnotation(Operate.class);
			}
			if(fd!=null){
				userOperatLog.setMean(fd.value());
				userOperatLog.setModule(fd.moduleName());
				userOperatLog.setSubModule(fd.subModuleName());
			}
			if(md!=null){
				userOperatLog.setFunction(md.value());
			}
			userOperatLog.setParamData(params);
			userOperatLog.setCreateTime(DateUtil.getTimeStamp());
			logger.info("业务处理"+",模块:["+(fd!=null?fd.moduleName():"")+"],操作:["+(md!=null?md.value():"")+"],调用类名称:["+className+"],调用方法名称:["+methodName+"],参数为:" + params + ";耗时" + stopWatch.getTotalTimeMillis() + "毫秒");
			userOperatLogService.insertBySelective(userOperatLog);
			//userOperatLogService.testasy();
			logger.info("执行完毕=======");
		}
	}

 

3,自定义注解三个

    功能模块注解

/**
 * 每个类的功能描述
 * @author zhangqh
 * @date 2016-8-2 下午01:03:59
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Function {
    String value() default "";
    String moduleName() default "";
    String subModuleName() default "";
}

 

操作方法注解

/**
 * 方法描述
 * @author zhangqh
 * @date 2016-8-2 下午12:55:25
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Operate {
    String value() default "";
}

 

不需要记录日志的注解

/**
 * 免记录日志注解标识
 * @author wjhu
 * @date 2016-8-2 下午01:03:59
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface NoLog {

}

 4,controller中记录操作日志的使用

/**
 * @Function注解为对应的操作日志模块
 * @author zhangqh
 *
 */
@Controller
@RequestMapping("/test")
@Function(value ="测试模块",moduleName = "测试模块",subModuleName = "")
public class test {
	/**
	 * 会记录对应的操作说明
	 */
	@Operate(value="操作")
	public void aa(){
		
	}
	/**
	 * 使用@NoLog注解就不是记录该方法的操作日志了
	 */
	@NoLog
	public void bb(){
		
	}
}

 

 提示:如果记录日志要持久化到数据库的话,建议入库操作加上异步操作这样对性能会提升不少

spring对异步调用方法支持也比较好 配置也比较简单,只需要要在配置文件中加入

<!-- 支持异步加载 -->
 <task:annotation-driven/>

 就可以了,然后使用的方法上加上@Async就可以了

分享到:
评论

相关推荐

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...

    spring aop 自定义注解保存操作日志到mysql数据库 源码

    4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...

    SpringMVC利用AOP实现自定义注解记录日志

    总结,Spring MVC结合AOP和自定义注解可以方便地实现日志记录功能,无需侵入业务代码。这种方法具有良好的可扩展性和灵活性,可以轻松适应不同场景的日志需求。同时,通过调整切面的定义,我们可以控制日志记录的...

    SpringBoot AOP各种注解、自定义注解、鉴权使用案例(免费下载)

    SpringBoot AOP,即面向切面编程,是Spring框架中的一个重要特性,用于实现代码的横切关注点,如日志记录、事务管理、权限验证等。AOP通过使用代理模式,将这些关注点与核心业务逻辑分离,使得代码更加模块化,更...

    spring中自定义注解(annotation)与AOP中获取注解

    通过这种方式,我们可以在AOP中灵活地处理带有自定义注解的方法,实现如日志记录、性能监控、权限验证等多种功能。这不仅提高了代码的复用性,也使得业务逻辑更加清晰。 总结来说,Spring中的自定义注解和AOP的结合...

    Spring AOP + 注解实现统一注解功能

    本文我们通过Spring AOP和Java的自定义注解来实现日志的插入功能,该方案对原有业务入侵较低,实现较灵活。下面我们将详细介绍该功能的实现原理和相关知识点。 1. 概述 在一般系统中,当我们做了一些重要的操作时...

    自定义注解实现伪动态传参的小demo

    在这个“自定义注解实现伪动态传参的小demo”中,我们将探讨如何创建一个自定义注解,以允许在注解中传递类似于动态参数的数据。 首先,自定义注解的定义通常以`@interface`关键字开始,我们可以定义一些元素(也...

    Spring 自定义注解的解析

    总的来说,Spring自定义注解的解析是一个强大且灵活的工具,可以帮助我们实现更精细化的代码组织和控制。结合`@ComponentScan`,我们可以轻松地在Spring环境中管理和利用自定义注解,进一步提升代码的可读性和可维护...

    Spring AOP 自定义注解的实现代码

    Spring AOP 自定义注解的实现代码 Spring AOP(Aspect-Oriented Programming)是一种面向方面编程的技术,它可以将散布在应用程序中的各种关注点(例如安全、日志、事务等)提取出来,形成一个独立的模块,以便于...

    spring AOP自定义注解方式实现日志管理的实例讲解

    在本文中,我们将探讨如何使用 Spring AOP 实现日志管理,并使用自定义注解方式来记录日志信息。这种方式可以灵活地实现日志管理,提高系统的可维护性和可扩展性。 首先,我们需要在 applicationContext-mvc.xml ...

    自定义注解+Spring AOP实现记录用户操作日志-附件资源

    自定义注解+Spring AOP实现记录用户操作日志-附件资源

    spring自定义注解样例

    总结来说,Spring自定义注解和AOP的结合使用,让我们能够灵活地在代码中插入跨切面的关注点,如日志记录、事务管理、性能监控等,而不必在每个方法中手动添加这些代码。这不仅提高了代码的整洁度,也使得系统更加...

    spring mvc + spring + hibernate 全注解整合开发视频教程 10

    同时,Spring的AOP机制允许我们定义横切关注点,如日志记录、事务管理等,使得代码更加模块化和易于维护。 Hibernate是Java领域中流行的ORM(对象关系映射)工具,它消除了直接操作数据库的需要。使用Hibernate,...

    springMVC AOP拦截拦截Controller等实现日志管理

    通过这种方式,我们可以在Spring MVC中利用AOP实现对Controller方法的透明日志管理,不仅记录正常流程,也能捕获和记录异常,提升系统的可维护性和问题排查效率。 在实际项目中,我们可以根据需求进一步定制日志...

    spring mvc + spring + hibernate 全注解整合开发视频教程 13

    同时,我们可以使用拦截器(Interceptor)来添加自定义的行为,如日志记录、权限检查等。 总的来说,本教程涵盖了Spring MVC、Spring和Hibernate的全注解集成,旨在帮助开发者理解如何在实际项目中有效地利用这些...

    java(spring boot)自定义注解

    总结来说,这个示例展示了如何在Spring Boot项目中自定义注解,将其应用于Java Bean的方法,以及如何利用AOP来实现全局扫描和自动执行。这样的实践在系统监控、性能分析和故障排查中非常有用,能够帮助开发者更好地...

    spring自定义注解+Aspect使用1

    在本文中,我们将学习如何在 Spring 项目中使用自定义注解和 Aspect 来实现日志记录功能。我们将从头开始,创建一个简单的 Spring Boot 项目,然后使用自定义注解和 Aspect 来实现日志记录。 自定义注解 首先,...

    spring boot aop记录修改前后的值demo

    spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

    Spring aop 记录操作日志 Aspect 源码

    总之,Spring AOP提供了一种优雅的方式来实现记录操作日志的需求,通过自定义Aspect和注解,我们可以灵活地控制哪些方法需要记录日志,以及记录什么样的日志信息。这个过程既提高了代码的可维护性,也使得日志管理...

Global site tag (gtag.js) - Google Analytics