Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
这里重点是执行的递归流程!非常漂亮的设计。
目录
1.进入DefaultAopProxyFactory选择何种代理
4.执行业务增强:DynamicAdvisedInterceptor的invoke
CGLIB和JDK都是继承ReflectiveMethodInvocation
排序在于ReflectiveAspectJAdvisorFactory这里设定了固定顺序。
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
if (methods.size() > 1) {
methods.sort(adviceMethodComparator);
}
return methods;
}
private static final Comparator<Method> adviceMethodComparator;
static {
// Note: although @After is ordered before @AfterReturning and @AfterThrowing,
// an @After advice method will actually be invoked after @AfterReturning and
// @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
// invokes proceed() in a `try` block and only invokes the @After advice method
// in a corresponding `finally` block.
Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
new InstanceComparator<>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
(Converter<Method, Annotation>) method -> {
AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (ann != null ? ann.getAnnotation() : null);
});
Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}
1.进入DefaultAopProxyFactory选择何种代理
判断条件:
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)))
2.JDK代理
示例:
public class ProxyTest {
@Test
public void testProxy() throws Throwable{
TestService testService = new TestServiceImpl();
MyInvocationHandler invocationHandler = new MyInvocationHandler(testService);
TestService proxy =(TestService) invocationHandler.getProxy();
proxy.businessFlow();
}
}
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target){
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(" ====================before proxy ================= ");
Object invoke = method.invoke(target, args);
System.out.println(" ====================after proxy ================= ");
return invoke;
}
public Object getProxy(){
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
}
}
public interface TestService {
String businessFlow() throws Exception;
}
public class TestServiceImpl implements TestService {
@Override
public String businessFlow() throws Exception {
System.out.println("================ TestServiceImpl businessFlow = processed .....");
return "businessFlow finished";
}
}
可见主要的类java.lang.reflect.Proxy
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
进入getProxyClass0方法创建proxy, JDK使用WeakCache对代理进行了缓存,如果已经存在相应的代理类,则直接返回,否则才会通过ProxyClassFactory来创建代理
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache(
new Proxy.KeyFactory(), new Proxy.ProxyClassFactory());
private static Class<?> getProxyClass0(ClassLoader var0, Class<?>... var1) {
if (var1.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
} else {
return (Class)proxyClassCache.get(var0, var1);
}
}
经过一番执行,最终会生成class代理文件,
package com.sun.proxy;
import com.example.sourcecodelearning.proxy.Subject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements Subject {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final void request() throws Exception {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (Exception | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.example.sourcecodelearning.proxy.Subject").getMethod("request");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
小结:
1.继承了Proxy类,实现了被代理的接口,由于java不能多继承,因此JDK的动态代理不支持对实现类的代理,只支持接口的代理。
2.提供了一个使用InvocationHandler作为参数的构造方法。
3.生成静态代码块来初始化接口中方法的Method对象,以及Object类的equals、hashCode、toString方法。
与静态代理相比,动态代理有更多优势,动态代理不仅不需要定义代理类,甚至可以在运行时指定代理类的执行逻辑,从而大大提升系统的灵活性。
目前动态代理类的生成方法有很多,有JDK自带的动态代理、CGLIB、Javassist和ASM库等。
- JDK动态代理:内置在JDK中,不需要引入第三方jar,使用简单,但功能比较弱。
- CGLIB/Javassist:这两个都是高级的字节码生成库,总体性能比JDK动态代理好,且功能强大。
- ASM:低级字节码生成工具,近乎使用bytecode编码,对开发人员要求最高。当然性能也是最好(相比前几种也不是很大的提升,这里不做具体介绍)。
JdkDynamicAopProxy的invoke
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
后面再分析。。。。
3.CglibAopProxy生成代理
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
1.getCallbacks设置拦截器链
封装进DynamicAdvisedInterceptor中
2.生成代理类
4.执行业务增强:DynamicAdvisedInterceptor的invoke
CGLIB中对于方法的拦截是通过将自定义的拦截器(实现MethodInterceptor接口)加入Callback中并在调用代理进直接激活拦截器中的intercept方法来实现的,那么在GetCallback中正是实现了这样一个目的,DynamicAdvisedInterceptor继承自MethodInterceptor中的intercept方法,所以,CGLIB方法的代理,核心实现必在DynamicAdvisedInterceptor的intercept中。
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
try {
retVal = methodProxy.invoke(target, argsToUse);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
主要就是:
- 获取拦截器链
- 如果链为空,直接执行;否则进入代理CglibMethodInvocation
CGLIB和JDK都是继承ReflectiveMethodInvocation
ReflectiveMethodInvocation执行
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
可通过下图的堆栈调用可看出,执行的过程是通过有顺序的Advisor拦截器来执行!
AfterReturningAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
MethodBeforeAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
ThrowsAdviceInterceptor
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
参考:
Spring源码分析-深入浅出AOP(图文分析)_进击的大叔的博客-CSDN博客
===========