Spring读源码系列之AOP--03---aop底层基础类学习

  • 引子
  • Spring AOP常用类解释
    • AopInfrastructureBean---免被AOP代理的标记接口
    • ProxyConfig---AOP配置类
      • ProxyProcessorSupport---代理创建器的通用实现
    • TargetClassAware---提供获取被代理类的接口
      • Advised---代理类配置信息封装
      • AdvisedSupport---Advised接口的实现类
    • AdvisorChainFactory--获取方法关联的拦截器链
      • DefaultAdvisorChainFactory---唯一的默认实现
    • AdvisorAdapter---advisor到methodinterceptor的适配器
    • AdvisorAdapterRegistry---管理AdvisorAdapter
      • DefaultAdvisorAdapterRegistry---默认实现
    • AdvisorAdapterRegistrationManager---注册自定义适配器
    • GlobalAdvisorAdapterRegistry ---发布一个全局共享的 DefaultAdvisorAdapterRegistry 实例
    • TargetClassAware---保留被代理对象类型
      • TargetSource--封装目标对象
    • AspectMetadat----切面的元数据类
      • Spring AOP切面实例化模型
    • AspectInstanceFactory---切面工厂
      • MetadataAwareAspectInstanceFactory---提供获取AspectMetadata的方法
        • BeanFactoryAspectInstanceFactory---IOC中获取切面
          • PrototypeAspectInstanceFactory----多例专用的工厂
  • org.aspectj包下的几个类
    • AjTypeSystem:从@Aspect的Class到AjType的工具类
    • AjType---封装切面元数据信息
      • AjTypeImpl

引子

就像IOC底层的实现依靠的是BeanWrapper,Convert,PropertyEditor这些基础设施类一样,AOP的实现底层也依赖了这样一批基础类,下面我们来看看。


Spring AOP常用类解释


AopInfrastructureBean—免被AOP代理的标记接口

AopInfrastructureBean是一个标记接口。若Bean实现了此接口,表明它是一个Spring AOP的基础类,那么这个类是不会被AOP给代理的,即使它能被切面切进去~~~

public interface AopInfrastructureBean {}

ProxyConfig—AOP配置类

用于创建代理的配置的父类,以确保所有代理创建者具有一致的属性。 它有五个属性,解释如下:

public class ProxyConfig implements Serializable {// 标记是否直接对目标类进行代理,而不是通过接口产生代理private boolean proxyTargetClass = false;// 标记是否对代理进行优化。true:那么在生成代理对象之后,如果对代理配置进行了修改,已经创建的代理对象也不会获取修改之后的代理配置。// 如果exposeProxy设置为true,即使optimize为true也会被忽略。private boolean optimize = false;// 标记是否需要阻止通过该配置创建的代理对象转换为Advised类型,默认值为false,表示代理对象可以被转换为Advised类型//Advised接口其实就代表了被代理的对象(此接口是Spring AOP提供,它提供了方法可以对代理进行操作,比如移除一个切面之类的),它持有了代理对象的一些属性,通过它可以对生成的代理对象的一些属性进行人为干预// 默认情况,我们可以这么完 Advised target = (Advised) context.getBean("opaqueTest"); 从而就可以对该代理持有的一些属性进行干预勒   若此值为true,就不能这么玩了boolean opaque = false;//标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。//当一个代理对象需要调用它【自己】的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。//实践场景:如何让被代理的方法在代理对象被代理的方法中被调用时,依旧能被拦截boolean exposeProxy = false;//标记是否需要冻结代理对象,即在代理对象生成之后,是否允许对其进行修改,默认为false.// 当我们不希望调用方修改转换成Advised对象之后的代理对象时,就可以设置为true 给冻结上即可private boolean frozen = false;...
}

ProxyProcessorSupport—代理创建器的通用实现

简单的说它就是提供为代理创建器提供了一些公共方法实现:

具有代理处理器通用功能的基类,特别是 ClassLoader 管理和 evaluateProxyInterfaces 算法。

@SuppressWarnings("serial")
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {/**
AOP的自动代理创建器必须在所有的别的processors之后执行,以确保它可以代理到所有的小伙伴们,即使需要双重代理得那种*/private int order = Ordered.LOWEST_PRECEDENCE;//代理类的类加载器@Nullableprivate ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();//代理类的类加载器是否被手动配置了---即用户是否手动指定了类加载器private boolean classLoaderConfigured = false;/**
Set the ordering which will apply to this processor's implementation of Ordered,
used when applying multiple processors.The default value is Ordered.LOWEST_PRECEDENCE, meaning non-ordered.*/public void setOrder(int order) {this.order = order;}@Overridepublic int getOrder() {return this.order;}/**
手动设置代理类加载器*/public void setProxyClassLoader(@Nullable ClassLoader classLoader) {this.proxyClassLoader = classLoader;//如果不为空,说明手动设置生效,打个标记this.classLoaderConfigured = (classLoader != null);}@Nullableprotected ClassLoader getProxyClassLoader() {return this.proxyClassLoader;}
//因为继承了BeanClassLoaderAware,因此默认的代理类加载器就是beanFactory用来加载所有bean的beanClassLoader@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {//手动配置的优先级更高,无法覆盖if (!this.classLoaderConfigured) {this.proxyClassLoader = classLoader;}}/*** Check the interfaces on the given bean class and apply them to the link ProxyFactory* if appropriate.* 检查给定类上的所有接口,然后检查分析决定代理方式*/protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {//拿到目标类上的所有接口Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());//是否存在合理的接口---可以决定是否采用jdk动态代理,如果为false则走cglib动态代理boolean hasReasonableProxyInterface = false;for (Class<?> ifc : targetInterfaces) {if (//pass内部的回调接口!isConfigurationCallbackInterface(ifc) && //pass内部语言接口!isInternalLanguageInterface(ifc) &&//当前接口内是否存在方法ifc.getMethods().length > 0) {hasReasonableProxyInterface = true;break;}}//如果存在合理的接口if (hasReasonableProxyInterface) {// Must allow for introductions; can't just set interfaces to the target's interfaces only.// 这里Spring的Doc特别强调了:不能值只把合理的接口设置进去,而是都得加入进去for (Class<?> ifc : targetInterfaces) {proxyFactory.addInterface(ifc);}}else {// 这个很明显设置true,表示使用CGLIB得方式去创建代理了~~~~//proxyFactory继承了proxyConfig,这里调用的是proxyConfig的setProxyTargetClass方法proxyFactory.setProxyTargetClass(true);}}/**
判断此接口类型是否属于:容器去回调的类型,这里例举处理一些接口 初始化、销毁、自动刷新、自动关闭、Aware感知等等*/protected boolean isConfigurationCallbackInterface(Class<?> ifc) {return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));}/**是否是如下通用的接口。若实现的是这些接口也会排除,不认为它是实现了接口的类*/protected boolean isInternalLanguageInterface(Class<?> ifc) {return (ifc.getName().equals("groovy.lang.GroovyObject") ||ifc.getName().endsWith(".cglib.proxy.Factory") ||ifc.getName().endsWith(".bytebuddy.MockAccess"));}}

TargetClassAware—提供获取被代理类的接口

/**
用于在代理后面公开目标类的最小接口。
由 AOP 代理对象和代理工厂(通过 org.springframework.aop.framework.Advised)以及 TargetSources 实现。*/
public interface TargetClassAware {@NullableClass<?> getTargetClass();}

Advised—代理类配置信息封装

Spring官方英文注释:

  • Interface to be implemented by classes that hold the configuration of a factory of AOP proxies. This configuration includes the Interceptors and other advice, Advisors, and the proxied interfaces.
  • Any AOP proxy obtained from Spring can be cast to this interface to allow manipulation of its AOP advice.

简单解释:

该接口用于保存一个代理的相关配置。比如保存了这个代理相关的拦截器、通知、增强器等等。

所有的代理对象都实现了该接口(我们就能够通过一个代理对象获取这个代理对象怎么被代理出来的相关信息)

不管是JDKproxy,还是cglib proxy,代理出来的对象都实现了org.springframework.aop.framework.Advised接口;


/*** Interface to be implemented by classes that hold the configuration* of a factory of AOP proxies. This configuration includes the* Interceptors and other advice, Advisors, and the proxied interfaces.** <p>Any AOP proxy obtained from Spring can be cast to this interface to* allow manipulation of its AOP advice.** @author Rod Johnson* @author Juergen Hoeller* @since 13.03.2003* @see org.springframework.aop.framework.AdvisedSupport*/
public interface Advised extends TargetClassAware {/*** Return whether the Advised configuration is frozen,* in which case no advice changes can be made.*/boolean isFrozen();/*** Are we proxying the full target class instead of specified interfaces?*/boolean isProxyTargetClass();/*** Return the interfaces proxied by the AOP proxy.* <p>Will not include the target class, which may also be proxied.*/Class<?>[] getProxiedInterfaces();/*** Determine whether the given interface is proxied.*/boolean isInterfaceProxied(Class<?> intf);/**
Change the TargetSource used by this Advised object.
Only works if the configuration isn't frozen.*/void setTargetSource(TargetSource targetSource);/*** Return the {@code TargetSource} used by this {@code Advised} object.*/TargetSource getTargetSource();/**
设置代理是否应由 AOP 框架公开为 ThreadLocal 以通过 AopContext 类进行获取It can be necessary to expose the proxy if an advised object needs to
invoke a method on itself with advice applied. Otherwise,
if an advised object invokes a method on this, no advice will be applied.
Default is false, for optimal performance.*/void setExposeProxy(boolean exposeProxy);/*** Return whether the factory should expose the proxy as a ThreadLocal.* It can be necessary to expose the proxy if an advised object needs* to invoke a method on itself with advice applied. Otherwise, if an* advised object invokes a method on this, no advice will be applied.* @see AopContext*/boolean isExposeProxy();/**
设置是否预过滤此代理配置,使其仅包含适用的advisors(匹配此代理的目标类)默认为“假”。如果advisors已经被预先过滤,则将此设置为“true”,这意味着在为代理调用构建实际advisors链时可以跳过 ClassFilter 检查。*/void setPreFiltered(boolean preFiltered);/*** Return whether this proxy configuration is pre-filtered so that it only* contains applicable advisors (matching this proxy's target class).*/boolean isPreFiltered();//操作当前代理对象advisors的相关方法Advisor[] getAdvisors();default int getAdvisorCount() {return getAdvisors().length;}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接口的实现类

它最重要的一个方法是:提供getInterceptorsAndDynamicInterceptionAdvice方法用来获取对应代理方法对应有效的拦截器链

AdvisedSupport本身不会提供创建代理的任何方法,专注于生成拦截器链。委托给ProxyCreatorSupport去创建代理对象

public class AdvisedSupport extends ProxyConfig implements Advised {private static final long serialVersionUID = 2651364800145442165L;/*** Canonical TargetSource when there's no target, and behavior is* supplied by the advisors.*/public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE;/** Package-protected to allow direct access for efficiency. */TargetSource targetSource = EMPTY_TARGET_SOURCE;/** Whether the Advisors are already filtered for the specific target class. */private boolean preFiltered = false;/**生产当前方法关联的拦截器链集合*/AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();/** Cache with Method as key and advisor chain List as value. */private transient Map<MethodCacheKey, List<Object>> methodCache;/*** Interfaces to be implemented by the proxy. Held in List to keep the order* of registration, to create JDK proxy with specified order of interfaces.* 代理类需要继承的接口*/private List<Class<?>> interfaces = new ArrayList<>();/*** List of Advisors. If an Advice is added, it will be wrapped* in an Advisor before being added to this List.*/private List<Advisor> advisors = new ArrayList<>();/**该方法是该类中最重要的一个方法,因此我把他移动到了最前面* Determine a list of MethodInterceptor objects* for the given method, based on this configuration.* 获取当前方法对应的拦截器链*/public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {//先构造缓存keyMethodCacheKey cacheKey = new MethodCacheKey(method);//先看缓存中是否存在List<Object> cached = this.methodCache.get(cacheKey);if (cached == null) {//缓存中没有,再通过advisorChainFactory得到当前方法关联的拦截器链,放入缓存中cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);this.methodCache.put(cacheKey, cached);}return cached;}/*** No-arg constructor for use as a JavaBean.*/public AdvisedSupport() {this.methodCache = new ConcurrentHashMap<>(32);}/*** Create a AdvisedSupport instance with the given parameters.*/public AdvisedSupport(Class<?>... interfaces) {this();setInterfaces(interfaces);}/*** Set the given object as target.* Will create a SingletonTargetSource for the object.*/public void setTarget(Object target) {//所有的目标对象都会被包装为TargetSource---默认为SingletonTargetSourcesetTargetSource(new SingletonTargetSource(target));}@Overridepublic void setTargetSource(@Nullable TargetSource targetSource) {this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);}@Overridepublic TargetSource getTargetSource() {return this.targetSource;}public void setTargetClass(@Nullable Class<?> targetClass) {this.targetSource = EmptyTargetSource.forClass(targetClass);}@Override@Nullablepublic Class<?> getTargetClass() {return this.targetSource.getTargetClass();}@Overridepublic void setPreFiltered(boolean preFiltered) {this.preFiltered = preFiltered;}@Overridepublic boolean isPreFiltered() {return this.preFiltered;}/*** Set the advisor chain factory to use.*/public void setAdvisorChainFactory(AdvisorChainFactory advisorChainFactory) {Assert.notNull(advisorChainFactory, "AdvisorChainFactory must not be null");this.advisorChainFactory = advisorChainFactory;}/*** Return the advisor chain factory to use (never {@code null}).*/public AdvisorChainFactory getAdvisorChainFactory() {return this.advisorChainFactory;}/*** Set the interfaces to be proxied.*/public void setInterfaces(Class<?>... interfaces) {Assert.notNull(interfaces, "Interfaces must not be null");this.interfaces.clear();for (Class<?> ifc : interfaces) {addInterface(ifc);}}/*** Add a new proxied interface.*/public void addInterface(Class<?> intf) {Assert.notNull(intf, "Interface must not be null");if (!intf.isInterface()) {throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");}if (!this.interfaces.contains(intf)) {this.interfaces.add(intf);adviceChanged();}}public boolean removeInterface(Class<?> intf) {return this.interfaces.remove(intf);}@Overridepublic Class<?>[] getProxiedInterfaces() {return ClassUtils.toClassArray(this.interfaces);}//当前接口是否被代理了@Overridepublic boolean isInterfaceProxied(Class<?> intf) {for (Class<?> proxyIntf : this.interfaces) {if (intf.isAssignableFrom(proxyIntf)) {return true;}}return false;}@Overridepublic final Advisor[] getAdvisors() {return this.advisors.toArray(new Advisor[0]);}@Overridepublic int getAdvisorCount() {return this.advisors.size();}@Overridepublic void addAdvisor(Advisor advisor) {int pos = this.advisors.size();addAdvisor(pos, advisor);}@Overridepublic void addAdvisor(int pos, Advisor advisor) throws AopConfigException {if (advisor instanceof IntroductionAdvisor) {validateIntroductionAdvisor((IntroductionAdvisor) advisor);}addAdvisorInternal(pos, advisor);}@Overridepublic boolean removeAdvisor(Advisor advisor) {int index = indexOf(advisor);if (index == -1) {return false;}else {removeAdvisor(index);return true;}}@Overridepublic void removeAdvisor(int index) throws AopConfigException {if (isFrozen()) {throw new AopConfigException("Cannot remove Advisor: Configuration is frozen.");}if (index < 0 || index > this.advisors.size() - 1) {throw new AopConfigException("Advisor index " + index + " is out of bounds: " +"This configuration only has " + this.advisors.size() + " advisors.");}Advisor advisor = this.advisors.remove(index);if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;// We need to remove introduction interfaces.for (Class<?> ifc : ia.getInterfaces()) {removeInterface(ifc);}}adviceChanged();}@Overridepublic int indexOf(Advisor advisor) {Assert.notNull(advisor, "Advisor must not be null");return this.advisors.indexOf(advisor);}@Overridepublic boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException {Assert.notNull(a, "Advisor a must not be null");Assert.notNull(b, "Advisor b must not be null");int index = indexOf(a);if (index == -1) {return false;}removeAdvisor(index);addAdvisor(index, b);return true;}/*** Add all of the given advisors to this proxy configuration.* @param advisors the advisors to register*/public void addAdvisors(Advisor... advisors) {addAdvisors(Arrays.asList(advisors));}/*** Add all of the given advisors to this proxy configuration.* @param advisors the advisors to register*/public void addAdvisors(Collection<Advisor> advisors) {if (isFrozen()) {throw new AopConfigException("Cannot add advisor: Configuration is frozen.");}if (!CollectionUtils.isEmpty(advisors)) {for (Advisor advisor : advisors) {if (advisor instanceof IntroductionAdvisor) {validateIntroductionAdvisor((IntroductionAdvisor) advisor);}Assert.notNull(advisor, "Advisor must not be null");this.advisors.add(advisor);}adviceChanged();}}private void validateIntroductionAdvisor(IntroductionAdvisor advisor) {advisor.validateInterfaces();// If the advisor passed validation, we can make the change.Class<?>[] ifcs = advisor.getInterfaces();for (Class<?> ifc : ifcs) {addInterface(ifc);}}private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {Assert.notNull(advisor, "Advisor must not be null");if (isFrozen()) {throw new AopConfigException("Cannot add advisor: Configuration is frozen.");}if (pos > this.advisors.size()) {throw new IllegalArgumentException("Illegal position " + pos + " in advisor list with size " + this.advisors.size());}this.advisors.add(pos, advisor);adviceChanged();}/*** Allows uncontrolled access to the {@link List} of {@link Advisor Advisors}.* Use with care, and remember to {@link #adviceChanged() fire advice changed events}* when making any modifications.*/protected final List<Advisor> getAdvisorsInternal() {return this.advisors;}@Overridepublic void addAdvice(Advice advice) throws AopConfigException {int pos = this.advisors.size();addAdvice(pos, advice);}/*** Cannot add introductions this way unless the advice implements IntroductionInfo.*/@Overridepublic void addAdvice(int pos, Advice advice) throws AopConfigException {Assert.notNull(advice, "Advice must not be null");if (advice instanceof IntroductionInfo) {// We don't need an IntroductionAdvisor for this kind of introduction:// It's fully self-describing.addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));}else if (advice instanceof DynamicIntroductionAdvice) {// We need an IntroductionAdvisor for this kind of introduction.throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");}else {addAdvisor(pos, new DefaultPointcutAdvisor(advice));}}@Overridepublic boolean removeAdvice(Advice advice) throws AopConfigException {int index = indexOf(advice);if (index == -1) {return false;}else {removeAdvisor(index);return true;}}@Overridepublic int indexOf(Advice advice) {Assert.notNull(advice, "Advice must not be null");for (int i = 0; i < this.advisors.size(); i++) {Advisor advisor = this.advisors.get(i);if (advisor.getAdvice() == advice) {return i;}}return -1;}/*** Is the given advice included in any advisor within this proxy configuration?*/public boolean adviceIncluded(@Nullable Advice advice) {if (advice != null) {for (Advisor advisor : this.advisors) {if (advisor.getAdvice() == advice) {return true;}}}return false;}/*** Count advices of the given class.*/public int countAdvicesOfType(@Nullable Class<?> adviceClass) {int count = 0;if (adviceClass != null) {for (Advisor advisor : this.advisors) {if (adviceClass.isInstance(advisor.getAdvice())) {count++;}}}return count;}/*** 新增加了一个adivce,那么缓存就失效了,因为对应方法的拦截器链可能发生的变化*/protected void adviceChanged() {this.methodCache.clear();}//...忽略不重要的方法/*** Simple wrapper class around a Method. Used as the key when* caching methods, for efficient equals and hashCode comparisons.* 用于缓存当前方法和对应方法关联拦截器链的方法缓存key*/private static final class MethodCacheKey implements Comparable<MethodCacheKey> {private final Method method;private final int hashCode;public MethodCacheKey(Method method) {this.method = method;this.hashCode = method.hashCode();}...}
}

AdvisorChainFactory–获取方法关联的拦截器链

public interface AdvisorChainFactory {/**
Determine a list of MethodInterceptors for the given advisor chain configuration.*/List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);}


该类只有一个默认实现


DefaultAdvisorChainFactory—唯一的默认实现

A simple but definitive way of working out an advice chain for a Method, given an Advised object. Always rebuilds each advice chain; caching can be provided by subclasses.

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {@Overridepublic List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.//AdvisorAdapterRegistry负责将advisor转换为MethodInterceptor//GlobalAdvisorAdapterRegistry获取到的是全局共享的AdvisorAdapterRegistry,下面会讲到AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();//获取应用到当前代理类上的所有增强器Advisor[] advisors = config.getAdvisors();List<Object> interceptorList = new ArrayList<>(advisors.length);Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());Boolean hasIntroductions = null;for (Advisor advisor : advisors) {//处理PointcutAdvisorif (advisor instanceof PointcutAdvisor) {// Add it conditionally.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) {//利用registry将advisor转换为MethodInterceptor[]MethodInterceptor[] interceptors = registry.getInterceptors(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));}}}}//处理IntroductionAdvisorelse if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {//利用registry将advisor转换为MethodInterceptor[]Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}//处理其他advisorelse {//利用registry将advisor转换为MethodInterceptor[]Interceptor[] interceptors = registry.getInterceptors(advisor);interceptorList.addAll(Arrays.asList(interceptors));}}return interceptorList;}/*** Determine whether the Advisors contain matching introductions.*/private static boolean hasMatchingIntroductions(Advisor[] advisors, Class<?> actualClass) {for (Advisor advisor : advisors) {if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;//IntroductionAdvisor只实现了类级别的过滤if (ia.getClassFilter().matches(actualClass)) {return true;}}}return false;}}

该类主要作用是从AdvisedSupport获取到当前代理对象上应用的advisors集合,然后将这些advisors集合转换为一组methodInterceptor返回


AdvisorAdapter—advisor到methodinterceptor的适配器

spring aop框架对BeforeAdvice、AfterAdvice、ThrowsAdvice三种通知类型的支持实际上是借助适配器模式来实现的,这样的好处是使得框架允许用户向框架中加入自己想要支持的任何一种通知类型

AdvisorAdapter是一个适配器接口,它定义了自己支持的Advice类型,并且能把一个Advisor适配成MethodInterceptor,以下是它的定义

public interface AdvisorAdapter {// 判断此适配器是否支持特定的Advice  boolean supportsAdvice(Advice advice);  // 将一个Advisor适配成MethodInterceptor  MethodInterceptor getInterceptor(Advisor advisor);
}

一般我们自己并不需要自己去提供此接口的实现,因为Spring为我们提供了对应的实现:

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {@Overridepublic boolean supportsAdvice(Advice advice) {return (advice instanceof MethodBeforeAdvice);}@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) {MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();return new MethodBeforeAdviceInterceptor(advice);}}
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {private final MethodBeforeAdvice advice;public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {Assert.notNull(advice, "Advice must not be null");this.advice = advice;}@Override@Nullablepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());return mi.proceed();}}

AdvisorAdapterRegistry—管理AdvisorAdapter

AdvisorAdapter注册表的接口。这是一个 SPI 接口,任何 Spring 用户都不能实现。

public interface AdvisorAdapterRegistry {//advice适配为AdvisorAdvisor wrap(Object advice) throws UnknownAdviceTypeException;
//advisor适配为MethodInterceptor[]MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
//注册AdvisorAdaptervoid registerAdvisorAdapter(AdvisorAdapter adapter);}

DefaultAdvisorAdapterRegistry—默认实现

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {private final List<AdvisorAdapter> adapters = new ArrayList<>(3);/*** 注册三个默认的适配器*/public DefaultAdvisorAdapterRegistry() {registerAdvisorAdapter(new MethodBeforeAdviceAdapter());registerAdvisorAdapter(new AfterReturningAdviceAdapter());registerAdvisorAdapter(new ThrowsAdviceAdapter());}//advice适配为advisor后返回@Overridepublic Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {if (adviceObject instanceof Advisor) {return (Advisor) adviceObject;}if (!(adviceObject instanceof Advice)) {throw new UnknownAdviceTypeException(adviceObject);}Advice advice = (Advice) adviceObject;if (advice instanceof MethodInterceptor) {// So well-known it doesn't even need an adapter.return new DefaultPointcutAdvisor(advice);}for (AdvisorAdapter adapter : this.adapters) {// Check that it is supported.if (adapter.supportsAdvice(advice)) {return new DefaultPointcutAdvisor(advice);}}throw new UnknownAdviceTypeException(advice);}//advisor适配为MethodInterceptor[]@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {List<MethodInterceptor> interceptors = new ArrayList<>(3);Advice advice = advisor.getAdvice();//如果本身就是MethodInterceptor,那就不需要进行适配,直接加入集合if (advice instanceof MethodInterceptor) {interceptors.add((MethodInterceptor) advice);}//AdvisorAdapter转换的都是本身并不是MethodInterceptor的advisorfor (AdvisorAdapter adapter : this.adapters) {if (adapter.supportsAdvice(advice)) {interceptors.add(adapter.getInterceptor(advisor));}}if (interceptors.isEmpty()) {throw new UnknownAdviceTypeException(advisor.getAdvice());}//一个advisor转换为一个MethodInterceptorreturn interceptors.toArray(new MethodInterceptor[0]);}@Overridepublic void registerAdvisorAdapter(AdvisorAdapter adapter) {this.adapters.add(adapter);}}

AdvisorAdapterRegistrationManager—注册自定义适配器

如果我们想把自己定义的AdvisorAdapter注册到spring aop框架中,怎么办?

  • 把我们自己写好得AdvisorAdapter放进Spring IoC容器中
  • 配置一个AdvisorAdapterRegistrationManager,它是一个BeanPostProcessor,它会检测所有的Bean。若是AdvisorAdapter类型,就:this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter)bean);
public class AdvisorAdapterRegistrationManager implements BeanPostProcessor {//获取到全局唯一共享的DefaultAdvisorAdapterRegistryprivate AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();/*** Specify the AdvisorAdapterRegistry to register AdvisorAdapter beans with.* Default is the global AdvisorAdapterRegistry.*/public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {this.advisorAdapterRegistry = advisorAdapterRegistry;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof AdvisorAdapter){this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter) bean);}return bean;}}

GlobalAdvisorAdapterRegistry —发布一个全局共享的 DefaultAdvisorAdapterRegistry 实例

Singleton 发布一个共享的 DefaultAdvisorAdapterRegistry 实例。

public final class GlobalAdvisorAdapterRegistry {private GlobalAdvisorAdapterRegistry() {}/*** Keep track of a single instance so we can return it to classes that request it.*/private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();/*** Return the singleton {@link DefaultAdvisorAdapterRegistry} instance.*/public static AdvisorAdapterRegistry getInstance() {return instance;}/*** Reset the singleton {@link DefaultAdvisorAdapterRegistry}, removing any* {@link AdvisorAdapterRegistry#registerAdvisorAdapter(AdvisorAdapter) registered}* adapters.*/static void reset() {instance = new DefaultAdvisorAdapterRegistry();}}

DefaultAdvisorChainFactory中就会用到这个类,来获取全局共享的DefaultAdvisorAdapterRegistry 实例


TargetClassAware—保留被代理对象类型

所有的Aop代理对象或者代理工厂(proxy factory)都要实现的接口,该接口用于暴露出被代理目标对象类型;

public interface TargetClassAware {@NullableClass<?> getTargetClass();}

TargetSource–封装目标对象

该接口代表一个目标对象,在aop调用目标对象的时候,使用该接口返回真实的对象。

比如它有其中两个实现SingletonTargetSource和PrototypeTargetSource代表着每次调用返回同一个实例,和每次调用返回一个新的实例

public interface TargetSource extends TargetClassAware {@Override@NullableClass<?> getTargetClass();/**
所有对 getTarget() 的调用都会返回相同的对象吗?这种情况下,就不需要调用releaseTarget(Object)了,AOP框架可以缓存getTarget()的返回值。单例可缓存*/boolean isStatic();/**
Return a target instance.
Invoked immediately before the AOP framework calls the "target" of an AOP method invocation.*/@NullableObject getTarget() throws Exception;/*** Release the given target object obtained from the method, if any.*/void releaseTarget(Object target) throws Exception;}

AspectMetadat----切面的元数据类

public class AspectMetadata implements Serializable {private final String aspectName;private final Class<?> aspectClass;// AjType这个字段非常的关键,它表示有非常非常多得关于这个切面的一些数据、方法(位于org.aspectj下)private transient AjType<?> ajType;// 解析切入点表达式用的,但是真正的解析工作为委托给`org.aspectj.weaver.tools.PointcutExpression`来解析的//若是单例:则是Pointcut.TRUE  否则为AspectJExpressionPointcutprivate final Pointcut perClausePointcut;public AspectMetadata(Class<?> aspectClass, String aspectName) {this.aspectName = aspectName;Class<?> currClass = aspectClass;AjType<?> ajType = null;// 此处会一直遍历到顶层知道Object  直到找到有一个是Aspect切面就行,然后保存起来// 因此我们的切面写在父类上 也是欧克的while (currClass != Object.class) {AjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass);if (ajTypeToCheck.isAspect()) {ajType = ajTypeToCheck;break;}currClass = currClass.getSuperclass();}// 由此可见,我们传进来的Class必须是个切面或者切面的子类的~~~if (ajType == null) {throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");}// 显然Spring AOP目前也不支持优先级的声明。。。if (ajType.getDeclarePrecedence().length > 0) {throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");}this.aspectClass = ajType.getJavaClass();this.ajType = ajType;// 切面的处在类型:PerClauseKind  由此可议看出,Spring的AOP目前只支持下面4种 switch (this.ajType.getPerClause().getKind()) {case SINGLETON:// 如国是单例,这个表达式返回这个常量this.perClausePointcut = Pointcut.TRUE;return;case PERTARGET:case PERTHIS:// PERTARGET和PERTHIS处理方式一样  返回的是AspectJExpressionPointcutAspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();ajexp.setLocation(aspectClass.getName());//设置好 切点表达式ajexp.setExpression(findPerClause(aspectClass));ajexp.setPointcutDeclarationScope(aspectClass);this.perClausePointcut = ajexp;return;case PERTYPEWITHIN:// Works with a type pattern// 组成的、合成得切点表达式~~~this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));return;default:// 其余的Spring AOP暂时不支持throw new AopConfigException("PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);}}private String findPerClause(Class<?> aspectClass) {String str = aspectClass.getAnnotation(Aspect.class).value();str = str.substring(str.indexOf('(') + 1);str = str.substring(0, str.length() - 1);return str;}...public Pointcut getPerClausePointcut() {return this.perClausePointcut;}// 判断perThis或者perTarger,最单实例、多实例处理public boolean isPerThisOrPerTarget() {PerClauseKind kind = getAjType().getPerClause().getKind();return (kind == PerClauseKind.PERTARGET || kind == PerClauseKind.PERTHIS);}// 是否是within的public boolean isPerTypeWithin() {PerClauseKind kind = getAjType().getPerClause().getKind();return (kind == PerClauseKind.PERTYPEWITHIN);}// 只要不是单例的,就都属于Lazy懒加载,延迟实例化的类型~~~~public boolean isLazilyInstantiated() {return (isPerThisOrPerTarget() || isPerTypeWithin());}
}

Spring AOP切面实例化模型

Spring AOP支持AspectJ的singleton、perthis、pertarget、pertypewithin实例化模型(目前不支持percflow、percflowbelow) 参见枚举类PerClauseKind

  • singleton:即切面只会有一个实例;
  • perthis:每个切入点表达式匹配的连接点对应的AOP对象(代理对象)都会创建一个新切面实例;
  • pertarget:每个切入点表达式匹配的连接点对应的目标对象都会创建一个新的切面实例
  • pertypewithin:

默认是singleton实例化模型,Schema风格只支持singleton实例化模型,而@AspectJ风格支持这三种实例化模型

singleton:使用@Aspect()指定,即默认就是单例实例化模式,在此就不演示示例了

perthis:每个切入点表达式匹配的连接点对应的AOP代理对象都会创建一个新的切面实例,使用@Aspect(“perthis(切入点表达式)”)指定切入点表达式;

// 他将为每个被切入点表达式匹配上的代理对象,都创建一个新的切面实例(此处允许HelloService是接口)
@Aspect("perthis(this(com.fsx.HelloService))")

pertarget:每个切入点表达式匹配的连接点对应的目标对象都会创建一个新的切面实例,使用@Aspect(“pertarget(切入点表达式)”)指定切入点表达式; 此处要求HelloService不能是接口

另外需要注意一点:若在Spring内要使用perthis和pertarget,请把切面的Scope定义为:prototype


AspectInstanceFactory—切面工厂

专门为切面创建实例的工厂(因为切面也不一定是单例的,也支持各种多例形式。上面已有说明)

// 它实现了Order接口哦~~~~支持排序的
public interface AspectInstanceFactory extends Ordered {//Create an instance of this factory's aspect.Object getAspectInstance();//Expose the aspect class loader that this factory uses.@NullableClassLoader getAspectClassLoader();
}

它的实现类如下:


SimpleAspectInstanceFactory:根据切面的aspectClass,调用空构造函数反射.newInstance()创建一个实例(备注:构造函数private的也没有关系)

SingletonAspectInstanceFactory:这个就更简单了,因为已经持有aspectInstance得引用了,直接return即可


MetadataAwareAspectInstanceFactory—提供获取AspectMetadata的方法

AspectInstanceFactory的子接口。提供了获取AspectMetadata的方法

public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {/*** Return the AspectJ AspectMetadata for this factory's aspect.*/AspectMetadata getAspectMetadata();/*** Return the best possible creation mutex for this factory.*/@NullableObject getAspectCreationMutex();}

SimpleMetadataAwareAspectInstanceFactory和SingletonMetadataAwareAspectInstanceFactory已经直接关联到AspectMetadata,所以直接return即可。

LazySingletonAspectInstanceFactoryDecorator也只是个简单的装饰而已。


BeanFactoryAspectInstanceFactory—IOC中获取切面

public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory, Serializable {// 持有对Bean工厂的引用private final BeanFactory beanFactory;// 需要处理的名称private final String name;private final AspectMetadata aspectMetadata;// 传了Name,type可议不传,内部判断出来public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name) {this(beanFactory, name, null);}public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, @Nullable Class<?> type) {this.beanFactory = beanFactory;this.name = name;Class<?> resolvedType = type;// 若没传type,就去Bean工厂里看看它的Type是啥  type不能为null~~~~if (type == null) {resolvedType = beanFactory.getType(name);Assert.notNull(resolvedType, "Unresolvable bean type - explicitly specify the aspect class");}// 包装成切面元数据类this.aspectMetadata = new AspectMetadata(resolvedType, name);}// 此处:切面实例 是从Bean工厂里获取的  需要注意// 若是多例的,请注意Scope的值@Overridepublic Object getAspectInstance() {return this.beanFactory.getBean(this.name);}@Override@Nullablepublic ClassLoader getAspectClassLoader() {return (this.beanFactory instanceof ConfigurableBeanFactory ?((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :ClassUtils.getDefaultClassLoader());}@Overridepublic AspectMetadata getAspectMetadata() {return this.aspectMetadata;}@Override@Nullablepublic Object getAspectCreationMutex() {if (this.beanFactory.isSingleton(this.name)) {// Rely on singleton semantics provided by the factory -> no local lock.return null;}else if (this.beanFactory instanceof ConfigurableBeanFactory) {// No singleton guarantees from the factory -> let's lock locally but// reuse the factory's singleton lock, just in case a lazy dependency// of our advice bean happens to trigger the singleton lock implicitly...return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();}else {return this;}}@Overridepublic int getOrder() {Class<?> type = this.beanFactory.getType(this.name);if (type != null) {if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();}// 若没实现接口,就拿注解的值return OrderUtils.getOrder(type, Ordered.LOWEST_PRECEDENCE);}return Ordered.LOWEST_PRECEDENCE;}
}

PrototypeAspectInstanceFactory----多例专用的工厂
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory implements Serializable {public PrototypeAspectInstanceFactory(BeanFactory beanFactory, String name) {super(beanFactory, name);// 若不是多例,直接报错了if (!beanFactory.isPrototype(name)) {throw new IllegalArgumentException("Cannot use PrototypeAspectInstanceFactory with bean named '" + name + "': not a prototype");}}
}

下面介绍下aspectj这个jar包下几个重要的类

org.aspectj包下的几个类

AjTypeSystem:从@Aspect的Class到AjType的工具类

public class AjTypeSystem {// 每个切面都给缓存上   注意:此处使用的是WeakReference 一定程度上节约内存private static Map<Class, WeakReference<AjType>> ajTypes = Collections.synchronizedMap(new WeakHashMap<Class,WeakReference<AjType>>());public static <T> AjType<T> getAjType(Class<T> fromClass) {WeakReference<AjType> weakRefToAjType =  ajTypes.get(fromClass);if (weakRefToAjType!=null) {AjType<T> theAjType = weakRefToAjType.get();if (theAjType != null) {return theAjType;} else {// 其实只有这一步操作:new AjTypeImpl~~~  AjTypeImpl就相当于代理了Class的很多事情~~~~theAjType = new AjTypeImpl<T>(fromClass);ajTypes.put(fromClass, new WeakReference<AjType>(theAjType));return theAjType;}}// neither key nor value was foundAjType<T> theAjType =  new AjTypeImpl<T>(fromClass);ajTypes.put(fromClass, new WeakReference<AjType>(theAjType));return theAjType;}
}

AjType—封装切面元数据信息

// 它继承自Java得Type和AnnotatedElement  它自己还提供了非常非常多的方法,基本都是获取元数据的一些方法,等到具体使用到的时候再来看也可以
public interface AjType<T> extends Type, AnnotatedElement {...
}

AjTypeImpl

AjTypeImpl是AjType的唯一实现类,因为方法实在是太多了,因此下面我只展示一些觉得比较有意思的方法实现:

public class AjTypeImpl<T> implements AjType<T> {private static final String ajcMagic = "ajc$";// 它真正传进来的,只是这个class,它是一个标注了@Aspect注解的Class类private Class<T> clazz;private Pointcut[] declaredPointcuts = null;private Pointcut[] pointcuts = null;private Advice[] declaredAdvice = null;private Advice[] advice = null;private InterTypeMethodDeclaration[] declaredITDMethods = null;private InterTypeMethodDeclaration[] itdMethods = null;private InterTypeFieldDeclaration[] declaredITDFields = null;private InterTypeFieldDeclaration[] itdFields = null;private InterTypeConstructorDeclaration[] itdCons = null;private InterTypeConstructorDeclaration[] declaredITDCons = null;// 唯一的一个构造函数public AjTypeImpl(Class<T> fromClass) {this.clazz = fromClass;}// 这个方法有意思的地方在于:它把所有的接口类,都变成AjType类型了public AjType<?>[] getInterfaces() {Class<?>[] baseInterfaces = clazz.getInterfaces();return toAjTypeArray(baseInterfaces);}private AjType<?>[] toAjTypeArray(Class<?>[] classes) {AjType<?>[] ajtypes = new AjType<?>[classes.length];for (int i = 0; i < ajtypes.length; i++) {ajtypes[i] = AjTypeSystem.getAjType(classes[i]);}return ajtypes;}// 就是把clazz返回出去public Class<T> getJavaClass() {return clazz;}public AjType<? super T> getSupertype() {Class<? super T> superclass = clazz.getSuperclass();return superclass==null ? null : (AjType<? super T>) new AjTypeImpl(superclass);}// 判断是否是切面,就看是否有这个注解~~public boolean isAspect() {return clazz.getAnnotation(Aspect.class) != null;}// 这个方法很重要:PerClause AspectJ切面的表现形式// 备注:虽然有这么多(参考这个类PerClauseKind),但是Spring AOP只支持前三种~~~public PerClause getPerClause() {if (isAspect()) {Aspect aspectAnn = clazz.getAnnotation(Aspect.class);String perClause = aspectAnn.value();if (perClause.equals("")) {// 如果自己没写,但是存在父类的话并且父类是切面,那就以父类的为准~~~~if (getSupertype().isAspect()) {return getSupertype().getPerClause();} // 不写默认是单例的,下面的就不一一解释了return new PerClauseImpl(PerClauseKind.SINGLETON);} else if (perClause.startsWith("perthis(")) {return new PointcutBasedPerClauseImpl(PerClauseKind.PERTHIS,perClause.substring("perthis(".length(),perClause.length() - 1));} else if (perClause.startsWith("pertarget(")) {return new PointcutBasedPerClauseImpl(PerClauseKind.PERTARGET,perClause.substring("pertarget(".length(),perClause.length() - 1));                } else if (perClause.startsWith("percflow(")) {return new PointcutBasedPerClauseImpl(PerClauseKind.PERCFLOW,perClause.substring("percflow(".length(),perClause.length() - 1));                              } else if (perClause.startsWith("percflowbelow(")) {return new PointcutBasedPerClauseImpl(PerClauseKind.PERCFLOWBELOW,perClause.substring("percflowbelow(".length(),perClause.length() - 1));} else if (perClause.startsWith("pertypewithin")) {return new TypePatternBasedPerClauseImpl(PerClauseKind.PERTYPEWITHIN,perClause.substring("pertypewithin(".length(),perClause.length() - 1));                } else {throw new IllegalStateException("Per-clause not recognized: " + perClause);}} else {return null;}}public AjType<?>[] getAjTypes() {Class[] classes = clazz.getClasses();return toAjTypeArray(classes);}public Field getDeclaredField(String name) throws NoSuchFieldException {Field f =  clazz.getDeclaredField(name);if (f.getName().startsWith(ajcMagic)) throw new NoSuchFieldException(name);return f;}// 这个有点意思:表示标注了@Before、@Around注解的并不算真的方法了,不会给与返回了public Method[] getMethods() {Method[] methods = clazz.getMethods();List<Method> filteredMethods = new ArrayList<Method>();for (Method method : methods) {if (isReallyAMethod(method)) filteredMethods.add(method);}Method[] ret = new Method[filteredMethods.size()];filteredMethods.toArray(ret);return ret;}private boolean isReallyAMethod(Method method) {if (method.getName().startsWith(ajcMagic)) return false;if (method.getAnnotations().length==0) return true;if (method.isAnnotationPresent(org.aspectj.lang.annotation.Pointcut.class)) return false;if (method.isAnnotationPresent(Before.class)) return false;if (method.isAnnotationPresent(After.class)) return false;if (method.isAnnotationPresent(AfterReturning.class)) return false;if (method.isAnnotationPresent(AfterThrowing.class)) return false;if (method.isAnnotationPresent(Around.class)) return false;return true;}// 拿到所有的Pointcut方法  并且保存缓存起来public Pointcut[] getDeclaredPointcuts() {if (declaredPointcuts != null) return declaredPointcuts;List<Pointcut> pointcuts = new ArrayList<Pointcut>();Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {Pointcut pc = asPointcut(method);if (pc != null) pointcuts.add(pc);}Pointcut[] ret = new Pointcut[pointcuts.size()];pointcuts.toArray(ret);declaredPointcuts = ret;return ret;}// 标注有org.aspectj.lang.annotation.Pointcut这个注解的方法。  相当于解析这个注解吧,最终包装成一个PointcutImpl// 主义:Spring-aop也有个接口Pointcut,这里也有一个Pointcut接口  注意别弄混了private Pointcut asPointcut(Method method) {org.aspectj.lang.annotation.Pointcut pcAnn = method.getAnnotation(org.aspectj.lang.annotation.Pointcut.class);if (pcAnn != null) {String name = method.getName();if (name.startsWith(ajcMagic)) {// extract real nameint nameStart = name.indexOf("$$");name = name.substring(nameStart +2,name.length());int nextDollar = name.indexOf("$");if (nextDollar != -1) name = name.substring(0,nextDollar);}return new PointcutImpl(name,pcAnn.value(),method,AjTypeSystem.getAjType(method.getDeclaringClass()),pcAnn.argNames());} else {return null;}}// 最终返回的对象为AdviceImpl实现类public Advice[] getDeclaredAdvice(AdviceKind... ofType) { ... }public Advice[] getAdvice(AdviceKind... ofType) { ... }private void initDeclaredAdvice() {Method[] methods = clazz.getDeclaredMethods();List<Advice> adviceList = new ArrayList<Advice>();for (Method method : methods) {Advice advice = asAdvice(method);if (advice != null) adviceList.add(advice);}declaredAdvice = new Advice[adviceList.size()];adviceList.toArray(declaredAdvice);}// 标注了各个注解的 做对应的处理private Advice asAdvice(Method method) {if (method.getAnnotations().length == 0) return null;Before beforeAnn = method.getAnnotation(Before.class);if (beforeAnn != null) return new AdviceImpl(method,beforeAnn.value(),AdviceKind.BEFORE);After afterAnn = method.getAnnotation(After.class);if (afterAnn != null) return new AdviceImpl(method,afterAnn.value(),AdviceKind.AFTER);AfterReturning afterReturningAnn = method.getAnnotation(AfterReturning.class);if (afterReturningAnn != null) {// 如果没有自己指定注解pointcut()的值,那就取值为value的值吧~~~String pcExpr = afterReturningAnn.pointcut();if (pcExpr.equals("")) pcExpr = afterReturningAnn.value();// 会把方法的返回值放进去、下同。。。   这就是@After和@AfterReturning的区别的原理// 它可议自定义自己的切点表达式咯return new AdviceImpl(method,pcExpr,AdviceKind.AFTER_RETURNING,afterReturningAnn.returning());}AfterThrowing afterThrowingAnn = method.getAnnotation(AfterThrowing.class);if (afterThrowingAnn != null) {String pcExpr = afterThrowingAnn.pointcut();if (pcExpr == null) pcExpr = afterThrowingAnn.value();return new AdviceImpl(method,pcExpr,AdviceKind.AFTER_THROWING,afterThrowingAnn.throwing());}Around aroundAnn = method.getAnnotation(Around.class);if (aroundAnn != null) return new AdviceImpl(method,aroundAnn.value(),AdviceKind.AROUND);return null;}// 必须不是切面才行哦~~~~public boolean isLocalClass() {return clazz.isLocalClass() && !isAspect();}public boolean isMemberClass() {return clazz.isMemberClass() && !isAspect();}// 内部类也是能作为切面哒  哈哈public boolean isMemberAspect() {return clazz.isMemberClass() && isAspect();}public String toString() { return getName(); }
}

Spring读源码系列之AOP--03---aop底层基础类学习相关推荐

  1. Spring IoC 源码系列(五)getBean 流程分析

    一.FactoryBean 用法讲解 在分析源码流程之前,我们先来看一下 FactoryBean,乍一看这家伙和 BeanFactory 很像,它们都可以用来获取 bean 对象,简单来说 Facto ...

  2. Spring IoC 源码系列(四)bean创建流程与循环依赖问题分析

    创建单例 bean 的代码细节在 org.springframework.beans.factory.support.AbstractBeanFactory#getBean 中,getBean 顾名思 ...

  3. Spring IoC 源码系列(一)BeanDefinition 初始化与注册

    一.BeanDefinition 1.1 什么是 BeanDefinition 在一般的 Spring 项目中,主要通过 XML 的方式配置 bean,而 BeanDefinition 就是 XML ...

  4. 鸟枪换炮读源码系列之ArrayList(java11)

    经常用到ArrayList,知道和LinkedList的对比优缺点,但是没那么读过源码. 首先它继承了AbstractList,实现了List接口,RandomAccess接口(支持快速随机访问,查询 ...

  5. Spring IoC 源码系列(三)Spring 事件发布机制原理分析

    在 IoC 容器启动流程中有一个 finishRefresh 方法,具体实现如下: protected void finishRefresh() {clearResourceCaches();init ...

  6. 带着问题读源码-soul(2021-01-16)

    ### 带着问题读源码系列之Dubbo插件 像往常一样启动 [soul-admin] 和 [soul-bootstrap] . 因为dubbo需要依赖zookeeper, 需要需要启动一个监听在 lo ...

  7. Spring 事务源码(2)—<tx:annotation-driven/>事务标签源码解析

      基于最新Spring 5.x,详细介绍了Spring 事务源码,包括< tx:annotation-driven/>标签源码解析.   此前我们已经学习了Spring的<tx:a ...

  8. Spring IoC 源码导读

    源码记录:spring-framework-5.1.7-source-code-read 文章导读 Spring IoC 源码系列(一)BeanDefinition 初始化与注册 Spring IoC ...

  9. 微信读书vscode插件_跟我一起读源码 – 如何阅读开源代码

    阅读是最好的老师 在学习和提升编程技术的时候,通过阅读高质量的源码,来学习专家写的高质量的代码,是一种非常有效的提升自我的方式.程序员群体是一群乐于分享的群体,因此在互联网上有大量的高质量开源项目,阅 ...

最新文章

  1. 第五次作业 何雅
  2. AI“重造”麻省理工学院!今宣布投资10亿美元成立全新计算学院,近70年来最大结构调整...
  3. 索引贴——移动开发(.Net CF 停止更新)
  4. 二叉树的深搜(DFS)与广搜(BFS)
  5. CSS---内外边距
  6. asp.net 按钮单击事件问题(自动弹出新窗口)
  7. java的int、char、long、float、double对byte的转换,在通信的时候会用到
  8. clion variable set
  9. 求二叉树中结点个数代码java_求二叉树中第K层结点的个数
  10. mysql sum带条件_mysql – SUM()基于SELECT的不同条件
  11. 欠拟合与过拟合概念和局部加权回归
  12. 使用typescript开发集成阿里云短信接口
  13. 16讲项目实战详细页制作及与首页和内页的链接添加
  14. Excel的一些函数操作
  15. inplace-operation-error 【已解决】
  16. 微软今天发布的紧急安全公告 MS08-067
  17. myEclipse8.5注册码
  18. SecureCRT快速连接服务器
  19. 3A游戏的未来:实景三维技术解放人工建模
  20. 抢茅台脚本居然用的Python,我们Python真是太强大了---图拉夫

热门文章

  1. 【机器学习】横向联邦学习纵向联邦学习区别
  2. 高并发、高可用、高负载、分布式架构
  3. GAN学习:一个简单的GAN搭建
  4. 《JavaScript百炼成仙》续集01. let强者,竟恐怖如斯
  5. java 操作 word 表格和样式_java 处理word文档 (含图片,表格内容)
  6. linux添加扩展gpio,嵌入式Linux工控板的ISA总线GPIO扩展
  7. wps里面函数怎么使用_WPS中函数的使用方法 - 卡饭网
  8. malloc申请内存空间失败
  9. 京东2018校招研发笔试题记录
  10. hdu多校第七场 1011 (hdu6656) Kejin Player 概率dp