在Spring项目中, 使用Spring AOP只需要3步.
1. 增加两个依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
2. 配置类上加EnableAspectJAutoProxy注解
配置类是有Configuration注解的类.
EnableAspectJAutoProxy注解用于开启aop功能, 和配置使用哪种代理, 默认是jdk的基于接口的代理(也可以用cglib的基于类的代理).
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}
3. 实现
3.1. 注解方式实现
- 在bean上加上Aspect注解, 表示这个bean是切面.
- 定义个通知方法, 通知器方法的参数必须是连接点, 方法上需要配置通知类型和切点的表达式.
package com.leolab.spring.demo.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
// 前置通知
@Before("execution(* com.leolab.spring.demo.*ServiceImpl.*(..))")
public void BeforePrintLog(JoinPoint joinPoint){
System.out.println("BeforePrintLog...");
}
// 环绕通知
@Around("execution(* com.leolab.spring.demo.*ServiceImpl.*(..))")
public Object AroundPrintLog(JoinPoint joinPoint) throws Throwable {
System.out.println("AroundPrintLog 1...");
ProceedingJoinPoint pjp = (ProceedingJoinPoint) joinPoint;
Object proceed = pjp.proceed();
System.out.println("AroundPrintLog 2...");
return proceed;
}
}
3.2. 代码方式实现
要继承AbstractPointcutAdvisor类, 实现通知器, 通知, 切点, 类过滤器, 方法匹配器
package com.leolab.spring.demo.aop;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
public class MyAdvisor extends AbstractPointcutAdvisor {
private Pointcut pc = new MyPointcut();
@Override
public Pointcut getPointcut() {
return pc;
}
@Override
public Advice getAdvice() {
return new MethodInterceptor(){
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// 前
System.out.println("MyAdvisor 11 ...");
// 继续调用拦截器或者目标方法
Object proceed = invocation.proceed();
// 后
System.out.println("MyAdvisor 22 ...");
return proceed;
}
};
}
}
class MyPointcut implements Pointcut{
private ClassFilter classFilter = new MyClassFilter();
private MethodMatcher methodMatcher = new MyMethodMatcher();
@Override
public ClassFilter getClassFilter() {
return classFilter;
}
@Override
public MethodMatcher getMethodMatcher() {
return methodMatcher;
}
}
class MyMethodMatcher implements MethodMatcher{
// 匹配List结尾的方法
@Override
public boolean matches(Method method, Class<?> targetClass) {
return method.getName().endsWith("List");
}
@Override
public boolean isRuntime() {
return false;
}
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
throw new UnsupportedOperationException();
}
}
class MyClassFilter implements ClassFilter{
// 匹配ServiceImpl结尾的方法
@Override
public boolean matches(Class<?> clazz) {
return clazz.getName().endsWith("ServiceImpl");
}
}