AOP系列文章链接地址
Spring AOP系列学习笔记一:AOP简介
Spring AOP系列学习笔记二:AOP入口分析
Spring AOP系列学习笔记三:AOP注解原理分析
Spring AOP系列学习笔记四:AOP具体调用流程分析
一、AOP常见概念
Joinpoint(连接点):在系统运行之前,AOP 的功能模块都需要织入到具体的功能模块中。要进行这种织入过程,我们需要知道在系统的哪些执行点上进行织入过程,这些将要在其之上进行织入操作的系统执行点就称之为 Joinpoint,最常见的 Joinpoint 就是方法调用。
Pointcut(切点):切点有有助于缩小切面所通知的连接点的范围,指定一组Joinpoint,定义了Advice发生的地方,例如:execution(* com.zgf.proxy.ProductImpl.*(…)).
Advice(通知/增强):定义了将会织入到Joinpoint的具体逻辑,通过注解 @Before、@After、@Around 来区别在 JointPoint 之前、之后还是环绕执行的代码。
Aspect(切面):Aspect 是对系统中的横切关注点逻辑进行模块化封装的 AOP 概念实体。类似于 Java 中的类声明,在 Aspect 中可以包含多个 Pointcut 以及相关的 Advice 定义。
Weaving(织入):织入指的是将 Advice 连接到 Pointcut 指定的 Joinpoint 处的过程,也称为:将 Advice 织入到 Pointcut 指定的 Joinpoint 处。
Target(目标对象):符合 Pointcut 所指定的条件,被织入 Advice 的对象。
一个简单的使用
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AopAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(AopAspect.class);
@Pointcut("execution(* com.joonwhee.open.demo.service..*.*(..))")
public void pointcut() {
}
@Before("pointcut()")
public void before() {
LOGGER.info("before advice");
}
@After("pointcut()")
public void after() {
LOGGER.info("after advice");
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws InterruptedException {
System.out.println("around advice start");
try {
Object result = proceedingJoinPoint.proceed();
System.out.println("result: " + result);
System.out.println("around advice end");
return result;
} catch (Throwable throwable) {
throwable.printStackTrace();
return null;
}
}
}
实现机制
SpringAOP实现代理模式有两种方式:
CGLIB动态代理与JDK动态代理区别
- java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
- 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
JDK动态代理
public class MyInvocationHandler implements InvocationHandler {
private Object origin;
public MyInvocationHandler(Object origin) {
this.origin = origin;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke start");
Object result = method.invoke(origin, args);
System.out.println("invoke end");
return result;
}
}
public class JdkProxyTest {
public static void main(String[] args) {
UserService proxy = (UserService) Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(),
new Class[]{UserService.class}, new MyInvocationHandler(new UserServiceImpl()));
proxy.doSomething();
}
}
CGLIB 代理
public class CglibInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("intercept start");
Object result = proxy.invokeSuper(obj, args);
System.out.println("intercept end");
return result;
}
}
public class CglibProxyTest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CglibObject.class);
enhancer.setCallback(new CglibInterceptor());
CglibObject proxy = (CglibObject) enhancer.create();
proxy.doSomething();
}
}