前几天做项目时,在做系统日志这一块,都是在每个方法里手写代码来添加,觉得很繁琐,考虑到spring有aop的功能,便寻思着用AOP来做这个日志功能。
首先需要传入日志记录的具体操作名称,我们可以用java的注解功能来带入参数,代码如下:
/** * 类的方法描述注解 * @author LuoYu */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface Log { /** 要执行的操作类型比如:add操作 **/ public String operationType() default ""; /** 要执行的具体操作比如:【添加仓库】 **/ public String operationName() default ""; }
注解类编写好之后,就要考虑spring我切面的问题目了,首先我们要创建一个切点,也就是需要插入的代码块,代码如下:
/** * 通过Spring AOP来添加系统日志 * @author LuoYu */ public class LogAspect extends BaseAction{ private static final long serialVersionUID = -5063868902693772455L; private Log logger = LogFactory.getLog(LogAspect.class); @SuppressWarnings( { "rawtypes", "unchecked" } ) public void doSystemLog(JoinPoint point) throws Throwable { Object[] param = point.getArgs(); Method method = null; String methodName = point.getSignature().getName(); if (!(methodName.startsWith("set") || methodName.startsWith("get")||methodName.startsWith("query"))){ Class targetClass = point.getTarget().getClass(); method = targetClass.getMethod(methodName, param[0].getClass()); if (method != null) { boolean hasAnnotation = method.isAnnotationPresent(com.tlj.pcxt.common.logaop.Log.class); if (hasAnnotation) { com.tlj.pcxt.common.logaop.Log annotation = method.getAnnotation(com.tlj.pcxt.common.logaop.Log.class); String methodDescp = annotation.operationType()+annotation.operationName(); if (logger.isDebugEnabled()) { logger.debug("Action method:" + method.getName() + " Description:" + methodDescp); } User appUser=(User) this.getHttpServletRequest().getSession().getAttribute("user"); if(appUser!=null){ try{ com.tlj.pcxt.entity.admin.Log logInfo=new com.tlj.pcxt.entity.admin.Log(); logInfo.setIp(this.getHttpServletRequest().getRemoteAddr()); logInfo.setSubmitUser(appUser); logInfo.setContent(annotation.operationType()+","+appUser.getUserName()+ "执行【"+annotation.operationName()+"】操作,影响数据的ID集合为["+getID(param[0])+"]"); this.logService.save(logInfo); }catch(Exception ex){ logger.error(ex.getMessage()); } } } } } } /** * 通过java反射来从传入的参数object里取出我们需要记录的id,name等属性, * 此处我取出的是id *@author 罗宇 *@date 2013-4-11 *@param obj *@return *@return String */ public String getID(Object obj){ if(obj instanceof String){ return obj.toString(); } PropertyDescriptor pd = null; Method method = null; String v = ""; try{ pd = new PropertyDescriptor("id", obj.getClass()); method = pd.getReadMethod(); v = String.valueOf(method.invoke(obj)); }catch (Exception e) { e.printStackTrace(); } return v; } }
切入代码编写好之后,需要在applicatioContext.xml里配置切入规则,也就是说要在哪些方法执行的时候来切入上面编写的代码:配置如 下:
<aop:aspectj-autoproxy/> <bean id="logAspect" class="com.tlj.pcxt.common.logaop.LogAspect"/> <aop:config> <aop:aspect ref="logAspect"> <aop:pointcut id="logPointCut" expression=" (execution(* com.tlj.pcxt.service.*.*Impl.add*(..))) or (execution(* com.tlj.pcxt.service.*.*Impl.update*(..))) or (execution(* com.tlj.pcxt.service.*.*Impl.delete*(..))) "/> <aop:after pointcut-ref="logPointCut" method="doSystemLog"/> </aop:aspect> </aop:config>
在此我配置的时在方法执行之后插入代码块
<aop:after pointcut-ref="logPointCut" method="doSystemLog"/>
并且是在所有以add,update,delete开头的方法才执行,其余的方法将不再匹配。
调用方法如下,
@Log(operationType="add操作:",operationName="添加仓库房间") public void addWareHouseRoom(WareHouseRoom wareHouseRoom) throws ServiceException { try{ this.getWareHouseRoomDao().save(wareHouseRoom); }catch (Exception e) { throw new ServiceException(e); } }
是在方法头前添加上面自定义的@Log注解,传入相关日志信息
另外,在LogAspect的doSystemLog方法里的
Object[] param = point.getArgs();
就是取出所匹配方法传入的参数,我们记录日志所需要的相关参数就是从这个对象里取出来的,并且在该方法下面的代码会检查所匹配的方法是否有注解@log,如果没有,会直接跳出该方法,不做任何处理.
相关推荐
4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...
总结一下,通过上述步骤,我们已经在Spring Boot应用中利用Spring AOP和注解方式实现了数据脱敏。这个拦截器可以在不修改原有业务代码的情况下,确保敏感信息在响应给客户端之前得到处理,提高了应用的安全性。同时...
5. **@EnableAspectJAutoProxy**: 在Spring配置类上添加此注解,启用基于Java代理的AOP支持,这样Spring会自动检测并处理带有@Aspect注解的类。 ```java @Configuration @EnableAspectJAutoProxy public class ...
本教程将详细介绍如何利用注解来配置和使用AOP来拦截Controller层的方法,以便记录执行过程中的相关信息,实现日志管理。 一、Spring AOP基础 AOP是Spring框架的核心组件之一,它允许程序员定义“切面”,这些切面...
Spring提供了两种主要的AOP实现方式:基于代理(Proxy-based)和基于注解(Annotation-based)。 - **基于代理的AOP**:Spring使用JDK动态代理或CGLIB动态代理创建目标对象的代理,代理对象在调用目标方法前后执行...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种强大的方式来实现横切关注点,如日志、事务管理、性能监控等,而无需侵入业务代码。下面将详细介绍Spring AOP的注解方式和XML配置方式。 ### ...
Spring Aop是基于AspectJ实现的面向切面编程(AOP),它提供了一个灵活的方式来实现日志管理。通过使用AspectJ注解,可以轻松地实现日志记录、性能监控、安全检查等功能。 知识点1: AspectJ注解 AspectJ是Java...
通过这种方式,Spring AOP允许我们以声明式的方式管理横切关注点,使得代码更加清晰和模块化。在`myaop`项目中,你可以找到具体的示例代码,包括切面类、切入点表达式以及相应的注解使用,通过这些示例可以更深入地...
本篇文章将深入探讨如何使用注解方式在Spring AOP中实现内部方法的拦截。 首先,理解AOP的基本概念至关重要。AOP的核心是切面(Aspect),它封装了横切关注点,即那些跨越多个对象的业务逻辑,如日志记录、事务管理...
在Spring框架中,AOP(面向切面编程)是一种...通过上述方式,我们可以有效地利用Spring AOP实现分层日志记录,提高代码的可维护性和问题排查效率。同时,合理的日志设计和管理对于任何应用程序来说都是至关重要的。
在本主题中,我们将深入探讨Spring AOP的注解版,它是基于Java注解的实现,简化了配置并提高了代码的可读性。 首先,让我们理解AOP的基本概念。AOP是一种编程范式,允许程序员定义“切面”,这些切面封装了跨越多个...
本项目旨在演示如何在Spring AOP中添加日志功能,以实现对应用程序执行过程的透明跟踪。通过使用Java 1.8,我们可以利用其新特性,如Lambda表达式,来简化代码。 首先,让我们理解Spring AOP的基本概念。AOP是面向...
本篇主要探讨的是如何利用Spring AOP的注解来实现这些功能,包括前置通知、后置通知、返回通知和异常通知。 ### 前置通知(Before通知) 前置通知在目标方法执行之前运行。在Spring AOP中,我们使用`@Before`注解...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。这些关注点通常与业务逻辑无关,但又在多个地方被用到,AOP就是为了...
本篇将通过注解方式探讨如何在Spring中实现AOP,基于提供的资源,我们可以看到一个实际的Demo项目结构。 首先,我们来看项目的基本结构: 1. `bin`目录:编译后的Java类文件会放在这里。 2. `.settings`目录:包含...
Spring AOP(面向切面编程)提供了一种优雅的方式来处理系统中的横切关注点,如日志、事务管理等。本篇文章将深入探讨如何在Spring中通过注解实现AOP。 首先,了解AOP的基本概念。面向切面编程是一种编程范式,它...
通过以上介绍,我们可以看到Spring的注解AOP配置是如何让代码更简洁、更易于理解和维护的。结合实际的项目需求,我们可以灵活地使用这些注解来实现各种企业级功能,如日志、事务控制等,从而提高代码的复用性和模块...
要启用注解驱动的 AOP,需要在 Spring 配置文件中添加 `<aop:aspectj-autoproxy>` 标签,或者在 Java 配置类中使用 `@EnableAspectJAutoProxy` 注解。 6. **运行环境** 由于这是一个简单的例子,因此运行环境的...
综上所述,Spring AOP提供了一种优雅的方式,让我们能够轻松地在不修改业务代码的情况下添加日志功能。通过理解并实践这个例子,开发者可以更好地掌握AOP在日志记载方面的应用,并将其运用到自己的项目中。
Spring AOP通过动态代理实现,有两种代理方式:JDK动态代理和CGLIB代理。JDK代理用于接口实现类,而CGLIB代理用于无接口或非代理类。 EL是JavaServer Faces (JSF) 和其他Java技术中用于在视图层解析表达式并获取...