public Object getProxy(ClassLoader classLoader) {return createAopProxy().getProxy(classLoader);}
//通过该方法决定使用jdk动态代理还是cglib动态代理
//1.如果目标对象实现了接口,使用jdk
//2.没有实现接口,使用cglib
//3.如果实现了接口,可以通过设置属性proxy-target-class为true强制使用cglib
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = TargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}return new ObjenesisCglibAopProxy(config);}else {return new JdkDynamicAopProxy(config);}
}
分析Proxy()方法
public Object getProxy(@Nullable ClassLoader classLoader) {if (logger.isDebugEnabled()) {logger.debug("Creating JDK dynamic proxy: target source is " + TargetSource());}//2.1获取需要代理的接口数组Class<?>[] proxiedInterfaces = AopProxyUtilspleteProxiedInterfaces(this.advised, true);//2.2查找需要代理的所有接口,查看每个接口里面是否equals方法或者hashcode方法,如果有就打个标记设为truefindDefinedEqualsAndHashCodeMethods(proxiedInterfaces);//2.3创建proxy代理对象wProxyInstance(classLoader, proxiedInterfaces, this);
}
该方法看着很长,其实就做了一件事情
为目标接口数组里面增加三个接口,1.springProxy接口,2.advised接口,3.decoratingProxy接口
然后返回接口数组
tatic Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {Class<?>[] specifiedInterfaces = ProxiedInterfaces();if (specifiedInterfaces.length == 0) {// No user-specified interfaces: check whether target class is an interface.Class<?> targetClass = TargetClass();if (targetClass != null) {if (targetClass.isInterface()) {advised.setInterfaces(targetClass);}else if (Proxy.isProxyClass(targetClass)) {advised.Interfaces());}specifiedInterfaces = ProxiedInterfaces();}}boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));int nonUserIfcCount = 0;if (addSpringProxy) {nonUserIfcCount++;}if (addAdvised) {nonUserIfcCount++;}if (addDecoratingProxy) {nonUserIfcCount++;}Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);int index = specifiedInterfaces.length;if (addSpringProxy) {proxiedInterfaces[index] = SpringProxy.class;index++;}if (addAdvised) {proxiedInterfaces[index] = Advised.class;index++;}if (addDecoratingProxy) {proxiedInterfaces[index] = DecoratingProxy.class;}return proxiedInterfaces;
}
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {for (Class<?> proxiedInterface : proxiedInterfaces) {Method[] methods = DeclaredMethods();for (Method method : methods) {if (AopUtils.isEqualsMethod(method)) {this.equalsDefined = true;}if (AopUtils.isHashCodeMethod(method)) {this.hashCodeDefined = true;}if (this.equalsDefined && this.hashCodeDefined) {return;}}}
}
jdkDynamicAopProxy实现了InnovacationHandler接口
所有在jdkDynamicAopProxy一定会有对invoke方法的回调
getPaoxy().wProxyInstance(classLoader, proxiedInterfaces, this);public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {MethodInvocation invocation;Object oldProxy = null;boolean setProxyContext = false;TargetSource targetSource = this.advised.targetSource;Object target = null;//这里会将equals方法和hashcode方法排除出去,使得这两个方法不会被增强try {if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {return equals(args[0]);}else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {return hashCode();}...Object retVal;//表示需要暴露Proxy,一般用于一个方法内部调用了该类的另一个方法if (poseProxy) {oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}target = Target();Class<?> targetClass = (target != null ? Class() : null);//3.1 获取拦截器链List<Object> chain = InterceptorsAndDynamicInterceptionAdvice(method, targetClass);//3.2 如果拦截器链为空if (chain.isEmpty()) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}//3.3如果拦截器链不为空else {invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);retVal = invocation.proceed();}Class<?> returnType = ReturnType();if (retVal != null && retVal == target &&returnType != Object.class && returnType.isInstance(proxy) &&!RawTargetAccess.class.DeclaringClass())) {retVal = proxy;}else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);}return retVal;}finally {if (target != null && !targetSource.isStatic()) {leaseTarget(target);}if (setProxyContext) {AopContext.setCurrentProxy(oldProxy);}}
}
此方法将advisor分为了三种:1.PointcutAdvisor 通过匹配class和method,将MethodInterceptor加入list里
2.IntroductionAdvisor,通过匹配class,将MethodInterceptor加入到list里
3.其他advisor,直接获取并保存到list里
@Overridepublic List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {// This is We have to process introductions first,// but we need to preserve order in the ultimate list.List<Object> interceptorList = new ArrayList<Object>(Advisors().length);Class<?> actualClass = (targetClass != null ? targetClass : DeclaringClass());boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);AdvisorAdapterRegistry registry = Instance();for (Advisor advisor : Advisors()) {if (advisor instanceof PointcutAdvisor) {// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;if (config.isPreFiltered() || Pointcut().getClassFilter().matches(actualClass)) {//匹配类MethodMatcher mm = Pointcut().getMethodMatcher();if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {//匹配方法MethodInterceptor[] interceptors = Interceptors(advisor);if (mm.isRuntime()) {// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {Interceptor[] interceptors = Interceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}else {Interceptor[] interceptors = Interceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}
通过advisor获得advice,如果advice是MethodInterceptor类型的直接加入
然后通过遍历adapter适配器,获得其他MethodInterceptor,比如用@Before注解得到的advice就是AspectJMethodBeforeAdvice,然后通过这一步包装成MethodInterceptor加入到list里
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {List<MethodInterceptor> interceptors = new ArrayList<>(3);Advice advice = Advice();if (advice instanceof MethodInterceptor) {interceptors.add((MethodInterceptor) advice);}for (AdvisorAdapter adapter : this.adapters) {if (adapter.supportsAdvice(advice)) {interceptors.Interceptor(advisor));}}if (interceptors.isEmpty()) {throw new Advice());}Array(new MethodInterceptor[0]);
}
直接调用被代理对象的方法,表示当前方法没有被增强
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);retVal = invocation.proceed();
创建一个MethodInvocation,然后调用methodInvocation的procee方法
补充:静态pointcut和动态pointcut,静态只需要匹配类和方法,动态多匹配一个参数
这个方法主要使用了责任链模式,使用一个索引currentInterceptorIndex来匹配,如果当前interceptor不是最后一个,
就执行增强逻辑,然后执行interceptor.invoke,在里面执行增强逻辑,然后再次调用this.proceed也就是invocaiton.proceed又回到这个方法继续执行下一个拦截器的增强逻辑
如果到了最后一个拦截器,就执行invokeJoinpoint(),也就是被代理方法本身的逻辑。
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.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;if (dm.methodMatcher.hod, this.targetClass, this.arguments)) {return dm.interceptor.invoke(this);}else {// Dynamic matching failed.// Skip this interceptor and invoke the next in urn proceed();}}else {// It's an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object urn ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}
}
本文发布于:2024-02-01 23:47:08,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170680740639952.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |