java利用AOP 实现操作日志记录(一)

本文介绍如何使用Spring AOP进行切面编程,包括配置、自定义注解、切面类定义及控制器和服务层的切面应用。通过示例展示了如何在Spring MVC项目中正确配置并使用AOP来拦截Controller请求。

 除springMvc外需要引入@Aspect注解依赖:

<!-- AOP -->
		<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
		<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.11</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.1_3</version>
        </dependency>

 

自定义注解标签:

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface logAnnotation {
	/**
	 * @param 模块名字
	 */
	String modelName() default "";

	/**
	 * @param 操作类型
	 */
	String option();
}

 

定义切面类:

@Aspect
// 该注解标示该类为切面类
@Component
// 注入依赖
public class OperationLogAspect {

	// 标注该方法体为后置通知,当目标方法执行成功后执行该方法体
	@AfterReturning("within(com.ustcinfo.fccos.terminal.web..*) && @annotation(rl)")
	public void addLogSuccess(JoinPoint jp, logAnnotation rl) {
		System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&");
		Object[] parames = jp.getArgs();// 获取目标方法体参数
		String className = jp.getTarget().getClass().toString();// 获取目标类名
		className = className.substring(className.indexOf("com"));
		String signature = jp.getSignature().toString();// 获取目标方法签名
		String methodName = signature.substring(signature.lastIndexOf(".") + 1, signature.indexOf("("));
		System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&");
	}

}

切面类可根据业务要求自行添加逻辑

 

在spring的容器xml中添加配置:

<aop:aspectj-autoproxy/>

此处有个注意点:网上说利用AOP无法拦截controller层,经测试,需要在web mvc中同时添加注解

<aop:aspectj-autoproxy/>

 因为为了启用事务,在spring的容器扫描中排除了controller层:

<context:annotation-config />
	<!-- 对应的是系统级别的配置,作用范围是系统上下文 -->
	<context:component-scan base-package="com.ustcinfo.fccos.terminal.web">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

 

在Mvc、中只启用了controller层的扫描:

<mvc:annotation-driven />
	<!-- 对应的是 controller 级别的配置,作用范围是控制层上下文。初始话转发内容 -->
	<context:component-scan base-package="com.ustcinfo.fccos.terminal.web.controller">
		<context:include-filter type="annotation"	expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

 

因此,只需要在 spring的父容器,mvc子容器中均添加

<aop:aspectj-autoproxy/>

 即可实现controller的拦截;

网上还有另外一种说法,就是配置文件改成

<aop:aspectj-autoproxy proxy-target-class="true"/>让spring使用cglib的代理方式

但是cglib的时候需要有默认的构造方法,class不能为final的,因此在项目中引入了mybatis或者其他的无默认构造的方法时候就会报错:

java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy33

091900_GvH6_2845376.png

,经测试,只需要在 spring的父容器,mvc子容器中均添加

<aop:aspectj-autoproxy/>

 即可实现controller以及其他业务的切面,网上说spring会自动在JDK动态代理和CGLIB之间转换,但是没做验证

查看aop是否生效

 

092739_ZoyS_2845376.png

切面注解controller

	@RequestMapping(value = "getInstallerInfos")
	@ResponseBody
	@logAnnotation(option = "查询装维_controller")
	public Json getInstallerInfos(String installer) {

 

092851_BLdi_2845376.png

	@Override
	@logAnnotation(option = "查询装维_service")
	public Json getInstallerInfos(String installer) {

切面注解service

日志均打印表明测试成功

转载于:https://my.oschina.net/AHdaibo/blog/1808603

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值