javascript
Spring AOP源码解析(三)—— AOP引入(续)
目錄
AbstractAspectJAdvisorFactory
AspectJAnnotation?
ReflectiveAspectJAdvisorFactory
getAdvisors
getAdvisor
?getPointcut
getAdvice
InstantiationModelAwarePointcutAdvisorImpl
ProxyFactory
TargetClassAware?
ProxyConfig?
Advised
AdvisedSupport
?AdvisorChainFactory
DefaultAdvisorChainFactory?
ProxyCreatorSupport
ProxyFactory實現
AopProxyFactory?
?DefaultAopProxyFactory
AopProxy
JdkDynamicAopProxy
?ReflectiveMethodInvocation
ObjenesisCglibAopProxy?
Proxy
上篇文章提到Advisor由AspectJAdvisorFactory 的具體實現類ReflectiveAspectJAdvisorFactory真正創建。然后由ProxyFactory使用Advisors實現代理對象的創建。
?
AbstractAspectJAdvisorFactory
AbstractAspectJAdvisorFactory主要提供了一些通用方法。主要主要涉及的AspectJ注解包括:
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};判斷是否有@Aspect注解。
@Overridepublic boolean isAspect(Class<?> clazz) {return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));}private boolean hasAspectAnnotation(Class<?> clazz) {return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);}?通過AnnotationUtils獲取注解信息。
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);if (foundAnnotation != null) {return foundAnnotation;}}return null;}@Nullableprivate static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {A result = AnnotationUtils.findAnnotation(method, toLookFor);if (result != null) {return new AspectJAnnotation<>(result);}else {return null;}}AspectJAnnotation?
AspectJAnnotation為AspectJ注解的包裝類。
//是什么注解 private final A annotation; //注解枚舉值 private final AspectJAnnotationType annotationType; //注解表達式 private final String pointcutExpression; //參數名稱 private final String argumentNames;static {annotationTypeMap.put(Pointcut.class, AspectJAnnotationType.AtPointcut);annotationTypeMap.put(Around.class, AspectJAnnotationType.AtAround);annotationTypeMap.put(Before.class, AspectJAnnotationType.AtBefore);annotationTypeMap.put(After.class, AspectJAnnotationType.AtAfter);annotationTypeMap.put(AfterReturning.class, AspectJAnnotationType.AtAfterReturning);annotationTypeMap.put(AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing);}ReflectiveAspectJAdvisorFactory
getAdvisors
?getAdvisors函數會獲取@Aspect修飾的實例中所有沒有被@Pointcut修飾的方法,然后調用getAdvisor函數,并且將這些方法作為參數。
@Overridepublic List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {//獲取Aspect類Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();validate(aspectClass);// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator// so that it will only instantiate once.MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);List<Advisor> advisors = new ArrayList<>();//獲取被@AspectJ注釋的所有方法。for (Method method : getAdvisorMethods(aspectClass)) {Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);if (advisor != null) {advisors.add(advisor);}}// If it's a per target aspect, emit the dummy instantiating aspect.if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);advisors.add(0, instantiationAdvisor);}// Find introduction fields.for (Field field : aspectClass.getDeclaredFields()) {Advisor advisor = getDeclareParentsAdvisor(field);if (advisor != null) {advisors.add(advisor);}}return advisors;}?沒有被@PointCut注解的,則返回。
private List<Method> getAdvisorMethods(Class<?> aspectClass) {final List<Method> methods = new ArrayList<>();ReflectionUtils.doWithMethods(aspectClass, method -> {// Exclude pointcutsif (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {methods.add(method);}}, ReflectionUtils.USER_DECLARED_METHODS);methods.sort(METHOD_COMPARATOR);return methods;}?
getAdvisor
生成Advisor,實際指:InstantiationModelAwarePointcutAdvisorImpl。
PointcutAdvisor實例中必然有一個Pointcut和Advice實例。修飾在方法上的注解包括:@Pointcut, @Around, @Before, @After, @AfterReturning和@AfterThrowing,所以InstantiationModelAwarePointcutAdvisorImpl會依據不同的不同的注解生成不同的Advice通知。
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName) { //判斷是否一個合法的AspectJ 類validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); // 獲得該方法上的切入點條件表達式AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());if (expressionPointcut == null) {return null;} //return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,this, aspectInstanceFactory, declarationOrderInAspect, aspectName);}?getPointcut
獲取切入點表達式。
@Nullableprivate AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { // 獲得該函數上@Pointcut, @Around, @Before, @After, @AfterReturning, @AfterThrowing注解的信息AspectJAnnotation<?> aspectJAnnotation =AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if (aspectJAnnotation == null) {return null;}AspectJExpressionPointcut ajexp =new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]); // 獲得注解信息中的切入點判斷表達式 ajexp.setExpression(aspectJAnnotation.getPointcutExpression());if (this.beanFactory != null) {ajexp.setBeanFactory(this.beanFactory);}return ajexp;}getAdvice
為AspectJ方法構造Advice。根據不同的Aspect注解生成不同的Advice。
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();validate(candidateAspectClass);//獲取方法上的AspectJ注解。AspectJAnnotation<?> aspectJAnnotation =AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);if (aspectJAnnotation == null) {return null;}//走到此處,說明是個AspectJ方法,判斷是@AspectJ注解的if (!isAspect(candidateAspectClass)) {//異常}AbstractAspectJAdvice springAdvice;//根據注解類型生成Advice。switch (aspectJAnnotation.getAnnotationType()) {case AtPointcut:return null;case AtAround:springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtBefore:springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfter:springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);break;case AtAfterReturning:springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();if (StringUtils.hasText(afterReturningAnnotation.returning())) {springAdvice.setReturningName(afterReturningAnnotation.returning());}break;case AtAfterThrowing:springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {springAdvice.setThrowingName(afterThrowingAnnotation.throwing());}break;default:throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);}// 配置Advice。springAdvice.setAspectName(aspectName);springAdvice.setDeclarationOrder(declarationOrder);String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);if (argNames != null) {springAdvice.setArgumentNamesFromStringArray(argNames);}springAdvice.calculateArgumentBindings();return springAdvice;}InstantiationModelAwarePointcutAdvisorImpl
InstantiationModelAwarePointcutAdvisorImpl的繼承結構如下圖,它本身是個Advisor,并且是個PointcutAdvisor。是對各種AspectJ 增強的封裝。
它包括以下屬性:
private static final Advice EMPTY_ADVICE = new Advice() {};private final AspectJExpressionPointcut declaredPointcut; //定義類型private final Class<?> declaringClass; //方法名private final String methodName; //參數類型private final Class<?>[] parameterTypes; //AspectJ方法private transient Method aspectJAdviceMethod;private final AspectJAdvisorFactory aspectJAdvisorFactory;private final MetadataAwareAspectInstanceFactory aspectInstanceFactory; //順序private final int declarationOrder; //AspectJ名稱private final String aspectName; //切點private final Pointcut pointcut; //private final boolean lazy; //Advice@Nullableprivate Advice instantiatedAdvice;@Nullableprivate Boolean isBeforeAdvice;@Nullableprivate Boolean isAfterAdvice;在構造函數中,會根據參數生成Advice。調用的aspectJAdvisorFactory的getAdvice方法。見前面內容。
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,this.aspectInstanceFactory, this.declarationOrder, this.aspectName);return (advice != null ? advice : EMPTY_ADVICE);}ProxyFactory
ProxyFactory是真正創建代理對象的類,其類繼承結構如下圖:
TargetClassAware?
public interface TargetClassAware {/**代理實現后面的目標類類型,可能是一個proxy,也可能是代理配置。*/@NullableClass<?> getTargetClass();}ProxyConfig?
上篇已介紹,主要是代理配置信息。
Advised
封裝代理配置信息的接口,配置包含:Interceptors 、other advice、 Advisors、proxied interfaces。
public interface Advised extends TargetClassAware {boolean isFrozen();/**是否代理的target class,而不是特定接口* Are we proxying the full target class instead of specified interfaces?*/boolean isProxyTargetClass();Class<?>[] getProxiedInterfaces();boolean isInterfaceProxied(Class<?> intf);void setTargetSource(TargetSource targetSource);TargetSource getTargetSource();void setExposeProxy(boolean exposeProxy);boolean isExposeProxy();void setPreFiltered(boolean preFiltered);boolean isPreFiltered();/*Advisor相關*/Advisor[] getAdvisors();void addAdvisor(Advisor advisor) throws AopConfigException;void addAdvisor(int pos, Advisor advisor) throws AopConfigException;boolean removeAdvisor(Advisor advisor);void removeAdvisor(int index) throws AopConfigException;int indexOf(Advisor advisor);boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;/*Advice相關*/void addAdvice(Advice advice) throws AopConfigException;void addAdvice(int pos, Advice advice) throws AopConfigException;boolean removeAdvice(Advice advice);int indexOf(Advice advice);String toProxyConfigString(); }AdvisedSupport
Advised的一個具體實現,就是怎么存、取屬性值。引入了AdvisorChainFactory 。
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();?AdvisorChainFactory
AdvisorChainFactory主要實現Advisor鏈。為指定方法構造Advisor鏈。默認實現為:DefaultAdvisorChainFactory。
public interface AdvisorChainFactory {List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);}DefaultAdvisorChainFactory?
返回方法的所有Advisor,根據Advisor類型來決定是否匹配方法。
@Overridepublic List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();//獲取所有Advisor。Advisor[] advisors = config.getAdvisors();List<Object> interceptorList = new ArrayList<>(advisors.length);//目標類實際類型。Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());Boolean hasIntroductions = null;//循環每個Advisor。for (Advisor advisor : advisors) {//切點類型Advisor。if (advisor instanceof PointcutAdvisor) {PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;//類類型是否匹配。if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();boolean match;if (mm instanceof IntroductionAwareMethodMatcher) {if (hasIntroductions == null) {hasIntroductions = hasMatchingIntroductions(advisors, actualClass);}match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);}else {match = mm.matches(method, actualClass);}//方法是否匹配if (match) {MethodInterceptor[] interceptors = registry.getInterceptors(advisor);//動態匹配。if (mm.isRuntime()) {for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));}}else {//靜態匹配。interceptorList.addAll(Arrays.asList(interceptors));}}}}//引介類型Advisor。else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;//引介類型 僅需要匹配 類類型。if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}//其他Advisor,默認表示匹配。else {Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}ProxyCreatorSupport
代理工廠的實現的基本支持類,引入了AopProxyFactory (DefaultAopProxyFactory)。并且通過AopProxyFactory.createAopProxy()創建AopProxy實例。
private AopProxyFactory aopProxyFactory;public ProxyCreatorSupport() {this.aopProxyFactory = new DefaultAopProxyFactory();} protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}ProxyFactory實現
ProxyFactory主要提供了些操作Advised屬性的方法,例如增加接口,設置TargetSource等,內部調用AopProxy.getProxy()方法生成代理實例。
AopProxyFactory?
根據代理配置信息,生成Aop代理。
public interface AopProxyFactory {AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;}?DefaultAopProxyFactory
根據代理配置信息,決定是使用JDK動態代理,還是cglib代理。
@Overridepublic AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {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.");}if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}return new ObjenesisCglibAopProxy(config);}else {return new JdkDynamicAopProxy(config);}}AopProxy
AopProxy是真正產生代理實例的類。包括JDK動態代理實現和cglib實現。
public interface AopProxy {Object getProxy();Object getProxy(@Nullable ClassLoader classLoader);}JdkDynamicAopProxy
JdkDynamicAopProxy又實現了InvocationHandler接口,使用java.lang.reflect.Proxy 通過反射來構造實例。JdkDynamicAopProxy的invoke方法中,如果有Advisor,則會生成一個ReflectiveMethodInvocation對象,執行增強。
@Overridepublic Object getProxy(@Nullable ClassLoader classLoader) {if (logger.isTraceEnabled()) {logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());}Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);} @Override@Nullablepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object oldProxy = null;boolean setProxyContext = false;TargetSource targetSource = this.advised.targetSource;Object target = null;try {//target自身沒有實現equal方法,if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {return equals(args[0]);}//target自身沒有實現hashCode方法,else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {return hashCode();}else if (method.getDeclaringClass() == DecoratingProxy.class) {// There is only getDecoratedClass() declared -> dispatch to proxy config.return AopProxyUtils.ultimateTargetClass(this.advised);}else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&method.getDeclaringClass().isAssignableFrom(Advised.class)) {// Service invocations on ProxyConfig with the proxy config...return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}Object retVal;if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}//獲取最后一個Target,targetSource的target會變化。target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);//獲取方法的攔截器鏈。List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);//如果沒有任何advice,直接調用 target的方法。if (chain.isEmpty()) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else {如果有advice,則構造MethodInvocation,調用proceed。MethodInvocation invocation =new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);retVal = invocation.proceed();}// Massage return value if necessary.Class<?> returnType = method.getReturnType();if (retVal != null && retVal == target &&returnType != Object.class && returnType.isInstance(proxy) &&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {//如果方法返回結果為this,則返回proxy。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()) {// 如果可能釋放target。targetSource.releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}}?ReflectiveMethodInvocation
屬性:
protected ReflectiveMethodInvocation(Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {this.proxy = proxy;this.target = target;this.targetClass = targetClass;this.method = BridgeMethodResolver.findBridgedMethod(method);this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;}proceed
?
@Override@Nullablepublic Object proceed() throws Throwable {// 最后一個攔截器,則調用invokeJoinpoint,使用代理的方法。if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}//循環攔截器。Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);//動態攔截器if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {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 {//不匹配,則下一個。return proceed();}}else {//靜態攔截器,直接調用增強方法。return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}ObjenesisCglibAopProxy?
不細談,具體的了解cglib相關知識。
Proxy
Proxy是反射包中的實現類。主要方法是newProxyInstance。
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{Objects.requireNonNull(h);final Class<?>[] intfs = interfaces.clone(); ... ... /** 調用native方法生成代理類.*/Class<?> cl = getProxyClass0(loader, intfs);try {if (sm != null) {checkNewProxyPermission(Reflection.getCallerClass(), cl);}//獲取代理類的構造函數。InvocationHandler.classfinal Constructor<?> cons = cl.getConstructor(constructorParams);... ... //實例化。return cons.newInstance(new Object[]{h});} catch (IllegalAccessException|InstantiationException e) {... ... }}?
?
總結
以上是生活随笔為你收集整理的Spring AOP源码解析(三)—— AOP引入(续)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring AOP源码解析(二)——
- 下一篇: gradle idea java ssm