JDK InvocationHandler --> CGLIB MethodInterceptor --> SpringAOP的底层 ProxyFactory --> bean初始化后生成代理的源码 --> @Aspect相关切面注解
1. jdk动态代理
// 接口
public interface OrderService {
String say();
}
// 实现类 结果为: "order service impl"
public class OrderServiceImpl implements OrderService {
@Override
public String say() {
return "order service impl";
}
}
// JDK动态代理
public class InvocationHandlerImpl implements InvocationHandler {
private Object needProxyObj;
public InvocationHandlerImpl(Object needProxyObj) {
this.needProxyObj = needProxyObj;
}
// 针对方法 做切面
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke before");
Object result = method.invoke(needProxyObj, args);
System.out.println("proxy return string : " + result);
System.out.println("invoke finished");
return result;
}
}
// 测试代理
public class InvocationTest {
public static void main(String[] args) {
// 代理是运行时的 设置 生成文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
OrderServiceImpl orderService = new OrderServiceImpl();
InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl(orderService);
// 生成代理
OrderService proxyOrderService = (OrderService) Proxy.newProxyInstance(orderService.getClass().getClassLoader(), orderService.getClass().getInterfaces(), invocationHandler);
proxyOrderService.say();
}
}
输出结果如下
Connected to the target VM, address: '127.0.0.1:62695', transport: 'socket'
invoke before
proxy return string : order service impl
invoke finished
Disconnected from the target VM, address: '127.0.0.1:62695', transport: 'socket'
2. cglib代理
// 定义一个类
public class OrderServiceImpl {
public String say() {
return "order service impl";
}
}
// 实现MethodInterceptor
public class MyMethodInterceptor implements MethodInterceptor {
// 切面
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("invoke before");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("cglib proxy return result : " + result);
System.out.println("invoke after");
return result;
}
}
// 测试
public class InterceptorTest {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
// 要代理的类
enhancer.setSuperclass(OrderServiceImpl.class);
// 使用哪一个实现了MyMethodInterceptor的类
enhancer.setCallback(new MyMethodInterceptor());
// 创建代理
OrderServiceImpl orderService = (OrderServiceImpl) enhancer.create();
orderService.say();
}
}
输出结果如下:
Connected to the target VM, address: '127.0.0.1:62510', transport: 'socket'
invoke before
cglib proxy return result : order service impl
invoke after
Disconnected from the target VM, address: '127.0.0.1:62510', transport: 'socket'
- jdk实现InvocationHandler类 重写invoke实现切面,cglib实现MethodInterceptor类 重写intercept实现切面
- jdk代理是生成代理对象 会调用invoke方法,cglib利用ASM技术 直接编译到class内
- jdk代理是作用在interface上, cglib代理可以是任意类 final除外
3. AOP底层ProxyFactory
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.6</version>
</dependency>
public class MyAdvisor implements PointcutAdvisor {
@Override
public Pointcut getPointcut() {
NameMatchMethodPointcut methodPointcut = new NameMatchMethodPointcut();
methodPointcut.addMethodName("say");
return methodPointcut;
}
@Override
public Advice getAdvice() {
MethodBeforeAdvice methodBeforeAdvice = new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行方法前"+method.getName());
}
};
return methodBeforeAdvice;
}
@Override
public boolean isPerInstance() {
return false;
}
}
3.1 从上述代码,可以看出Advisor与Advice的关系,我们可以理解Advice是一个建议,Advisor是一个统筹,Pointcut是一个切点,这个方法就是针对代理的对象的say方法进行before切面。
在Spring中,Advice分为:
前置Advice:MethodBeforeAdvice
后置Advice:AfterReturningAdvice
环绕Advice:MethodInterceptor
异常Advice:ThrowsAdvice
public static void main(String[] args) {
// ProxyFactory spring的代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 目标对象
proxyFactory.setTarget(new OrderServiceImpl());
// 选填 实现的接口
proxyFactory.setInterfaces(OrderService.class);
// 添加Advisor 加载切面逻辑
proxyFactory.addAdvisor(new MyAdvisor());
// 获得代理对象
OrderService orderService = (OrderService) proxyFactory.getProxy();
orderService.say();
}
3.2 从这三个创建代理形式可以看出来,创建代理要具备三个条件。(1. 目标对象 2.切面逻辑 3.根据1和2创建代理对象)
3.3 接下来 着重看一下proxyFactory.getProxy()方法的实现 也是到底选择JDK动态代理 还是CGLIB代理的实现
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// proxyFactory可以设置isOptimize属性
// EnableAspectJAutoProxy注解的proxyTargetClass属性
// Class<?>[] ifcs = config.getProxiedInterfaces();
// (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])))
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 一般来讲target都是一个对象 很少进这个方法
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 如果不干预设置ProxyFactory属性 ProxyFactory没有添加interfaces
return new ObjenesisCglibAopProxy(config);
}
else {
// 如果不干预设置ProxyFactory属性 ProxyFactory添加了interfaces
return new JdkDynamicAopProxy(config);
}
}
4. SpringAOP 实例化后postProcessAfterInitialization后置处理器:第一个记载Advisor相关逻辑 着重看第二个
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 最重要的方法 wrapIfNecessary 如果需要AOP 则AOP
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 实例化前生成aop代理的 直接return
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 一些特殊类 直接return
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 寻找符合条件的候选Advistor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建AOP
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 底层创建代理 就是ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// setInterfaces
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 构建Advisor 切面逻辑
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 生成代理
return proxyFactory.getProxy(getProxyClassLoader());
}
5. @Aspect 对应的一些切面注解
5.1 @Before对应的是AspectJMethodBeforeAdvice,直接实现MethodBeforeAdvice,在进行动态代理时会把AspectJMethodBeforeAdvice转成MethodBeforeAdviceInterceptor,也就转变成了MethodBeforeAdviceInterceptor
a. 先执行advice对应的方法
b. 再执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
5.2 @After对应的是AspectJAfterAdvice,直接实现了MethodInterceptor
a. 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
b. 再执行advice对应的方法
5.3 @Around对应的是AspectJAroundAdvice,直接实现了MethodInterceptor
a. 直接执行advice对应的方法
5.4 @AfterThrowing对应的是AspectJAfterThrowingAdvice,直接实现了MethodInterceptor
a. 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
b. 如果上面抛了Throwable,那么则会执行advice对应的方法
5.5 @AfterReturning对应的是AspectJAfterReturningAdvice,实现了AfterReturningAdvice,在进行动态代理时会把AspectJAfterReturningAdvice转成AfterReturningAdviceInterceptor,也就转变成了MethodInterceptor
a. 先执行MethodInvocation的proceed(),会执行下一个Interceptor,如果没有下一个Interceptor了,会执行target对应的方法
b. 执行上面的方法后得到最终的方法的返回值
c. 再执行Advice对应的方法