Spring aop aspectj
maven依赖
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>4.3.24.RELEASE</spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
AopConfig.java
package com.sky.springtest.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ComponentScan(basePackages = {"com.sky.springtest"})
@ImportResource({"spring-aop.xml"})
//@EnableAspectJAutoProxy 注解方式激活aspectj的自动代理功能
public class AopConfig {}
spring-aop.xml 激活aspectj的自动代理功能
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 激活自动代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
StudentService 使用注解的被拦截类
package com.sky.springtest.service;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import com.sky.springtest.entity.Student;
@Service
public class StudentService {
private static Logger logger = Logger.getLogger(StudentService.class);
public void add() {
logger.info("StudentService-add");
// throw new RuntimeException("测试异常");
}
public void edit(Student student) {
logger.info("StudentService-edit" + student);
// throw new RuntimeException("测试异常");
}
}
TestAspectAdd 编写切面一
package com.sky.springtest.aspect;
import org.apache.log4j.Logger;
import org.aspectj.lang.*;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import com.sky.springtest.service.StudentService;
@Aspect
@Component
public class TestAspectAdd {
private static Logger logger = Logger.getLogger(TestAspectAdd.class);
@Before(value = "execution(* com.sky.springtest.service.StudentService.add(..))")
public void before(JoinPoint joinPoint) {
// 调用对象
StudentService target = (StudentService) joinPoint.getTarget();
// 参数
Object[] args = joinPoint.getArgs();
logger.info("TestAspect-before[target=" + target + ", args=" + args.length + "]");
}
@After("execution(* com.sky.springtest.service.StudentService.add())")
public void after(JoinPoint joinPoint) {
logger.info("TestAspect-after");
}
@AfterReturning(value = "execution(* com.sky.springtest.service.StudentService.add(..))", returning = "returnVal")
public void afterReturning(JoinPoint joinPoint, Object returnVal) {
logger.info("TestAspect-afterReturning=" + returnVal);
}
@AfterThrowing(value = "execution(* com.sky.springtest.service.StudentService.add())", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {
logger.info("TestAspect-afterThrowing=" + e.getMessage());
}
@Around("execution(* com.sky.springtest.service.StudentService.add())")
public Object around(ProceedingJoinPoint joinpoint) {
Object result = null;
logger.info("TestAspect-around-start");
try {
result = joinpoint.proceed();
} catch (Throwable e) {
logger.info("TestAspect-around-err=" + e.getMessage());
}
logger.info("TestAspect-around-result=" + result);
logger.info("TestAspect-around-end");
return result;
}
}
定义切入点
上面重复使用这个 execution(* com.sky.springtest.service.StudentService.add())
这个切入点
可以优化成
@Pointcut(value = "execution(* com.sky.springtest.service.StudentService.add(..))")
public void testAspectAddPointCut() {}
@Before(value = "testAspectAddPointCut()")
public void before(JoinPoint joinPoint) {...}
@After(value = "testAspectAddPointCut()")
public void after(JoinPoint joinPoint) {...}
@AfterReturning(value = "testAspectAddPointCut()", returning = "returnVal")
public void afterReturning(JoinPoint joinPoint, Object returnVal) {...}
@AfterThrowing(value = "testAspectAddPointCut()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {...}
@Around("testAspectAddPointCut()")
public Object around(ProceedingJoinPoint joinpoint) {...}
测试切面TestAspectAdd
private static ApplicationContext context = null;
@BeforeClass
public static void beforeClass() {
context = new AnnotationConfigApplicationContext(AopConfig.class);
}
@Test
public void testAdd() {
StudentService studentService = context.getBean(StudentService.class);
studentService.add();
}
/* 测试结果:
[04 14:09:57,264 INFO ] [main] aspect.TestAspectAdd - TestAspect-around-start
[04 14:09:57,265 INFO ] [main] aspect.TestAspectAdd - TestAspect-before[target=com.sky.springtest.service.StudentService@4de4b452, args=0]
[04 14:09:57,284 INFO ] [main] service.StudentService - StudentService-add
[04 14:09:57,284 INFO ] [main] aspect.TestAspectAdd - TestAspect-around-result=null
[04 14:09:57,284 INFO ] [main] aspect.TestAspectAdd - TestAspect-around-end
[04 14:09:57,285 INFO ] [main] aspect.TestAspectAdd - TestAspect-after
[04 14:09:57,285 INFO ] [main] aspect.TestAspectAdd - TestAspect-afterReturning=null
*/
TestAspectEdit 编写切面二
切面一获取参数是通过joinPoint.getArgs()
得到的
还可以通过下面的方法
注意注解的参数的名称和方法的参数名称保持一致
@Before(value = "execution(* com.sky.springtest.service.StudentService.edit(..)) && args(student)")
public void before(JoinPoint joinPoint, Student student) { }
@Pointcut(value = "execution(* com.sky.springtest.service.StudentService.edit(..)) && args(student) ")
public void studentServiceEditPointcut(Student student) { }
@After(value = "studentServiceEditPointcut(b)")
public void after(JoinPoint joinPoint, Student b) { }
@AfterReturning(value = "studentServiceEditPointcut(c)", returning = "returnVal")
public void afterReturning(JoinPoint joinPoint, Student c, Object returnVal) { }