xml配置拦截器
<bean id="operationAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="interceptorNames"> <list><value>recordHistoryInterceptor</value></list> </property> <property name="beanNames"> <list> <value>podUnitMemberService</value> </list> </property> </bean>
<bean id="recordHistoryInterceptor" class="com.umgsai.interceptor.RecordHistoryInterceptor" />
public class RecordHistoryInterceptor implements MethodInterceptor { @Setter private HistoryRecorder historyRecorder; public Object invoke(MethodInvocation invocation) throws Throwable { Object result = null; try { result = invocation.proceed(); } catch (Exception e) { result = e.getMessage(); throw e; } finally { historyRecorder.recordHistory(invocation.getMethod(), invocation.getArguments(), result); } return result; } }
public void recordHistory(Method method, Object[] params, Object result) throws Throwable { OperationRecord annotation = method.getAnnotation(OperationRecord.class); if (annotation != null) { if (params.length > 0) { try { //1. 如果dataType是GLOBAL if (annotation.dataType() == DataTypeEnum.GLOBAL) { recordProject(annotation, params, result); } else {//2. 如果dataType不是GLOBAL,如BASIC,APP_RELATE recordApp(annotation, method, params, result); } } catch (Exception e) { logger.error("recordHistory error:" + e.getMessage(), e); } } else { logger.warn("含有注解@OperationRecord的方法" + method.getName() + "没有包含参数!"); } } }
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface OperationRecord { OperationTypeEnum operationType(); DataTypeEnum dataType(); }
public interface PodUnitMemberService { //podUnitAppName为podUnitMember类中的属性 @OperationRecord(dataType = DataTypeEnum.BASIC, operationType = OperationTypeEnum.INSERT) long insert(@IdentifierAnnotation(name = "podUnitAppName") PodUnitMember podUnitMember); }
private void recordApp(OperationRecord annotation, Method method, Object[] params, Object result) throws Throwable { ZappinfoOperationLogDO operationLogDO = new ZappinfoOperationLogDO(); //2.1 设置dataType为注解里的dataType operationLogDO.setDataType(annotation.dataType().getCode()); //2.2 获取参数注解信息 Annotation[][] paraAnnotationArray = method.getParameterAnnotations(); //2.3 遍历参数注解信息 Object identifier = null; for (int index = 0; index < paraAnnotationArray.length; index++) { for (Annotation anno : paraAnnotationArray[index]) { //2.3.1 如果注解是TargetAnnotation if (anno instanceof TargetAnnotation) { //2.3.1.1 appName是从参数中获取 if (((TargetAnnotation) anno).targetSource() == TargetSourceEnum.PARAMETER) { operationLogDO.setAppName(params[index].toString()); //2.3.1.2 appName是从参数的属性中获取,通过反射调用getAppName方法 } else if (((TargetAnnotation) anno).targetSource() == TargetSourceEnum.ATTRIBUTE) { operationLogDO.setAppName(params[index].getClass() .getDeclaredMethod("getAppName").invoke(params[index]).toString()); } //2.3.2 如果注解是DataTypeAnnotation } else if (anno instanceof DataTypeAnnotation) { String dataType = null; if (((DataTypeAnnotation) anno).dataTypeSource() == DataSourceTypeEnum.CLASS) { dataType = dataTypeMap.get(params[index].getClass()); } else if (((DataTypeAnnotation) anno).dataTypeSource() == DataSourceTypeEnum.STRING) { dataType = dataTypeMap.get(params[index]); } if (StringUtil.isNotBlank(dataType)) { operationLogDO.setDataType(dataType); } else { logger.warn("没有找到" + params[index].getClass() + "对应的数据类型!"); } } else if (anno instanceof IdentifierAnnotation) { //通过IdentifierAnnotation注解获取名称 IdentifierAnnotation idanno = (IdentifierAnnotation) anno; String name = idanno.name(); identifier = params[index]; if (StringUtil.isNotBlank(name)) { Object obj = params[index]; Field field = obj.getClass().getDeclaredField(name); field.setAccessible(true); //去注解中配置的属性名称的值 identifier = field.get(obj); } } } } if (identifier == null) { fillDO(operationLogDO, annotation, params, result); zappinfoOperationLogDAO.insertOperatinoLog(operationLogDO); identifier = operationLogDO.getAppName(); } addOperationRecord(annotation, identifier, method, params, result); }
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface IdentifierAnnotation { String name(); }
相关推荐
spring aop实现接口参数变更前后对比和日志记录完整代码,拿到项目代码,只需要做数据库连接的修改即可运行起来使用,代码案例详细,真是可靠,代码原文地址:...
1. **切面(Aspect)**:切面是关注点的模块化,比如日志记录、事务管理、性能监控等。在Spring AOP中,切面由通知(Advice)和切点(Pointcut)定义。 2. **通知(Advice)**:通知是在特定连接点(Join Point)...
Spring AOP,全称为Aspect-Oriented Programming,是Spring框架中的一个重要组成部分,主要用来处理系统的横切关注点,如日志记录、事务管理、性能监控等。这些关注点通常会分散在应用程序的各个角落,而AOP就是为了...
在Java开发中,Spring AOP(面向切面编程)是一个强大的功能,用于实现日志记录。AOP允许我们在不修改原有代码的情况下,插入新的行为,比如日志记录,事务管理等。下面将详细介绍如何在Spring框架中使用AOP来实现...
总结来说,Spring AOP日志框架允许我们通过注解方式轻松地实现业务日志管理,提高代码的可读性和可维护性,同时减少了代码冗余。通过自定义切面和通知,我们可以灵活地控制日志记录的时机和内容,满足不同场景的需求...
例如,我们可以定义一个切面来处理日志记录,这样就无需在每个被记录的方法中插入日志代码。只需在切面中定义切入点(pointcut)表达式,匹配需要记录日志的方法,然后在通知(advice)中编写日志逻辑即可。 在实际...
- **日志记录**:在方法调用前后记录操作信息。 - **事务管理**:自动进行事务的开启、提交、回滚等操作。 - **权限控制**:在访问敏感资源前进行权限检查。 - **性能监控**:记录方法执行时间,分析系统性能瓶颈。 ...
Spring AOP(面向切面编程)是...这样,我们可以保持业务逻辑的清晰,同时实现系统级的服务,如事务管理、日志记录、性能监控等。在实际项目中,正确配置和使用这些依赖库,对于实现高效、灵活的面向切面编程至关重要。
9. **应用场景**:Spring AOP常用于日志记录、事务管理、性能监控、安全性控制等。例如,你可以定义一个切面来记录所有服务层方法的调用,或者在每次数据库操作前开启事务并在操作成功后提交事务。 通过以上介绍,...
1. **Aspect**:切面是AOP的核心概念,它封装了特定的横切关注点,例如事务管理和日志记录。一个切面可以包含多个通知(Advice)和切点(Pointcut)。 2. **Joinpoint**:连接点是指程序执行过程中的一个特定时刻,...
在`springAop1`这个压缩包中,可能包含了一个简单的应用示例,展示了如何定义一个切面类,以及如何在该类中定义通知方法。例如,我们可能会看到一个名为`LoggingAspect`的类,其中包含了`@Before`注解的方法,用于在...
在这个场景中,我们将使用Spring AOP来实现一个日志记录的功能,以追踪系统中各个方法的调用情况,包括访问时间以及传递的参数。下面将详细阐述如何实现这一目标。 首先,我们需要了解AOP的基本概念。AOP的核心是切...
在Java应用中,AOP主要用于日志记录、性能统计、安全控制、事务管理等方面,通过将这些通用功能模块化,可以避免重复代码,提高代码的可维护性和复用性。 Spring AOP的实现基于动态代理,有两种代理方式:JDK动态...
5. **运行与测试**:完成以上步骤后,启动Spring容器,当`MyService`的方法被调用时,将会先执行`logBefore`方法的日志记录。 通过这种方式,Spring AOP允许我们在不修改业务代码的情况下,轻松地添加和管理横切...
AOP是一种编程范式,旨在解决程序中的横切关注点问题,这些关注点通常与业务逻辑无关,但又需要在多个地方被调用,如日志记录、性能统计、异常处理等。AOP通过将这些关注点与核心业务逻辑分离,使得代码更加模块化...
其中,Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它为开发者提供了在不侵入业务代码的情况下,进行日志记录、性能监控、事务管理等横切关注点的能力。本文将深入探讨...
在Java应用程序中,AOP主要用于日志记录、性能统计、安全控制、事务管理等跨切面的关注点。下面将详细介绍Spring AOP的关键知识点以及与其相关的jar包。 1. **AOP概念**: - **切面(Aspect)**:AOP的核心概念,...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它允许程序员在不修改源代码的情况下,通过在运行时插入额外的行为(如日志记录、性能监控等)来增强对象的功能。动态代理则是Spring AOP实现的核心技术之一...
Spring AOP有两种实现方式:基于代理的AOP(JDK动态代理和CGLIB代理)和基于注解的AOP。 - **JDK动态代理**:当目标类实现了接口时,Spring会使用JDK的Proxy类创建一个代理对象,该代理对象会在调用接口方法时插入...
在这个入门实例中,我们将深入理解Spring AOP如何实现简单日志记录。 首先,AOP的核心概念包括切面(Aspect)、通知(Advice)、连接点(Join Point)、切入点(Pointcut)和织入(Weaving)。切面是AOP中的核心...