栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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 {

	
	private int order = Ordered.LOWEST_PRECEDENCE;
    
    //代理类的类加载器
	@Nullable
	private ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();
    
    //代理类的类加载器是否被手动配置了---即用户是否手动指定了类加载器
	private boolean classLoaderConfigured = false;


	
	public void setOrder(int order) {
		this.order = order;
	}

	@Override
	public int getOrder() {
		return this.order;
	}

	
	public void setProxyClassLoader(@Nullable ClassLoader classLoader) {
		this.proxyClassLoader = classLoader;
		//如果不为空,说明手动设置生效,打个标记
		this.classLoaderConfigured = (classLoader != null);
	}
	
	@Nullable
	protected ClassLoader getProxyClassLoader() {
		return this.proxyClassLoader;
	}
//因为继承了BeanClassLoaderAware,因此默认的代理类加载器就是beanFactory用来加载所有bean的beanClassLoader
	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
	//手动配置的优先级更高,无法覆盖
		if (!this.classLoaderConfigured) {
			this.proxyClassLoader = classLoader;
		}
	}


	
	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);
		}
	}

	
	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—提供获取被代理类的接口
public interface TargetClassAware {

	@Nullable
	Class 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接口;


public interface Advised extends TargetClassAware {

	
	boolean isFrozen();

	
	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();


//操作当前代理对象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;

	
	public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE;


	
	TargetSource targetSource = EMPTY_TARGET_SOURCE;

	
	private boolean preFiltered = false;

	
	AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();

	
	private transient Map> methodCache;

	
	private List> interfaces = new ArrayList<>();

	
	private List advisors = new ArrayList<>();



	
	public List getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class targetClass) {
	//先构造缓存key
		MethodCacheKey cacheKey = new MethodCacheKey(method);
	//先看缓存中是否存在
		List cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			//缓存中没有,再通过advisorChainFactory得到当前方法关联的拦截器链,放入缓存中
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}


	
	public AdvisedSupport() {
		this.methodCache = new ConcurrentHashMap<>(32);
	}

	
	public AdvisedSupport(Class... interfaces) {
		this();
		setInterfaces(interfaces);
	}


	
	public void setTarget(Object target) {
	   //所有的目标对象都会被包装为TargetSource---默认为SingletonTargetSource
		setTargetSource(new SingletonTargetSource(target));
	}

	@Override
	public void setTargetSource(@Nullable TargetSource targetSource) {
		this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);
	}

	@Override
	public TargetSource getTargetSource() {
		return this.targetSource;
	}

	public void setTargetClass(@Nullable Class targetClass) {
		this.targetSource = EmptyTargetSource.forClass(targetClass);
	}

	@Override
	@Nullable
	public Class getTargetClass() {
		return this.targetSource.getTargetClass();
	}

	@Override
	public void setPreFiltered(boolean preFiltered) {
		this.preFiltered = preFiltered;
	}

	@Override
	public boolean isPreFiltered() {
		return this.preFiltered;
	}

	
	public void setAdvisorChainFactory(AdvisorChainFactory advisorChainFactory) {
		Assert.notNull(advisorChainFactory, "AdvisorChainFactory must not be null");
		this.advisorChainFactory = advisorChainFactory;
	}

	
	public AdvisorChainFactory getAdvisorChainFactory() {
		return this.advisorChainFactory;
	}


	
	public void setInterfaces(Class... interfaces) {
		Assert.notNull(interfaces, "Interfaces must not be null");
		this.interfaces.clear();
		for (Class ifc : interfaces) {
			addInterface(ifc);
		}
	}

	
	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);
	}

	@Override
	public Class[] getProxiedInterfaces() {
		return ClassUtils.toClassArray(this.interfaces);
	}

//当前接口是否被代理了
	@Override
	public boolean isInterfaceProxied(Class intf) {
		for (Class proxyIntf : this.interfaces) {
			if (intf.isAssignableFrom(proxyIntf)) {
				return true;
			}
		}
		return false;
	}


	@Override
	public final Advisor[] getAdvisors() {
		return this.advisors.toArray(new Advisor[0]);
	}

	@Override
	public int getAdvisorCount() {
		return this.advisors.size();
	}

	@Override
	public void addAdvisor(Advisor advisor) {
		int pos = this.advisors.size();
		addAdvisor(pos, advisor);
	}

	@Override
	public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
		if (advisor instanceof IntroductionAdvisor) {
			validateIntroductionAdvisor((IntroductionAdvisor) advisor);
		}
		addAdvisorInternal(pos, advisor);
	}

	@Override
	public boolean removeAdvisor(Advisor advisor) {
		int index = indexOf(advisor);
		if (index == -1) {
			return false;
		}
		else {
			removeAdvisor(index);
			return true;
		}
	}

	@Override
	public 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();
	}

	@Override
	public int indexOf(Advisor advisor) {
		Assert.notNull(advisor, "Advisor must not be null");
		return this.advisors.indexOf(advisor);
	}

	@Override
	public 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;
	}

	
	public void addAdvisors(Advisor... advisors) {
		addAdvisors(Arrays.asList(advisors));
	}

	
	public void addAdvisors(Collection 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();
	}

	
	protected final List getAdvisorsInternal() {
		return this.advisors;
	}

	@Override
	public void addAdvice(Advice advice) throws AopConfigException {
		int pos = this.advisors.size();
		addAdvice(pos, advice);
	}

	
	@Override
	public 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));
		}
	}

	@Override
	public boolean removeAdvice(Advice advice) throws AopConfigException {
		int index = indexOf(advice);
		if (index == -1) {
			return false;
		}
		else {
			removeAdvisor(index);
			return true;
		}
	}

	@Override
	public 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;
	}

	
	public boolean adviceIncluded(@Nullable Advice advice) {
		if (advice != null) {
			for (Advisor advisor : this.advisors) {
				if (advisor.getAdvice() == advice) {
					return true;
				}
			}
		}
		return false;
	}

	
	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;
	}
	
	
	protected void adviceChanged() {
		this.methodCache.clear();
	}
	
	//...忽略不重要的方法
	
	
	private static final class MethodCacheKey implements Comparable {

		private final Method method;

		private final int hashCode;

		public MethodCacheKey(Method method) {
			this.method = method;
			this.hashCode = method.hashCode();
		}
       ...
	}
}

 

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

	
	List 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 {

	@Override
	public List 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 interceptorList = new ArrayList<>(advisors.length);
		Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		Boolean hasIntroductions = null;

		for (Advisor advisor : advisors) {
		//处理PointcutAdvisor
			if (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));
						}
					}
				}
			}
			//处理IntroductionAdvisor
			else 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));
				}
			}
			//处理其他advisor
			else {
			//利用registry将advisor转换为MethodInterceptor[]
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

	
	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 {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public 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
	@Nullable
	public 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适配为Advisor
	Advisor wrap(Object advice) throws UnknownAdviceTypeException;
//advisor适配为MethodInterceptor[]
	MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
//注册AdvisorAdapter
	void registerAdvisorAdapter(AdvisorAdapter adapter);

}

DefaultAdvisorAdapterRegistry—默认实现
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

	private final List adapters = new ArrayList<>(3);


	
	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}


//advice适配为advisor后返回
	@Override
	public 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[]
	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List interceptors = new ArrayList<>(3);
		Advice advice = advisor.getAdvice();
		//如果本身就是MethodInterceptor,那就不需要进行适配,直接加入集合
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		//AdvisorAdapter转换的都是本身并不是MethodInterceptor的advisor
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		//一个advisor转换为一个MethodInterceptor
		return interceptors.toArray(new MethodInterceptor[0]);
	}

	@Override
	public 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 {
    //获取到全局唯一共享的DefaultAdvisorAdapterRegistry
	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();


	
	public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
		this.advisorAdapterRegistry = advisorAdapterRegistry;
	}


	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Override
	public 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() {
	}


	
	private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

	
	public static AdvisorAdapterRegistry getInstance() {
		return instance;
	}

	
	static void reset() {
		instance = new DefaultAdvisorAdapterRegistry();
	}

}

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


TargetClassAware—保留被代理对象类型

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

public interface TargetClassAware {
	@Nullable
	Class getTargetClass();

}

TargetSource–封装目标对象

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

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

public interface TargetSource extends TargetClassAware {

	@Override
	@Nullable
	Class getTargetClass();

	
	boolean isStatic();

	
	@Nullable
	Object getTarget() throws Exception;

	
	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  否则为AspectJExpressionPointcut
	private 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处理方式一样  返回的是AspectJExpressionPointcut
				AspectJExpressionPointcut 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.
	@Nullable
	ClassLoader getAspectClassLoader();
}

它的实现类如下:


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

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


MetadataAwareAspectInstanceFactory—提供获取AspectMetadata的方法

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

public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {

	
	AspectMetadata getAspectMetadata();

	
	@Nullable
	Object 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的值
	@Override
	public Object getAspectInstance() {
		return this.beanFactory.getBean(this.name);
	}

	@Override
	@Nullable
	public ClassLoader getAspectClassLoader() {
		return (this.beanFactory instanceof ConfigurableBeanFactory ?
				((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
				ClassUtils.getDefaultClassLoader());
	}

	@Override
	public AspectMetadata getAspectMetadata() {
		return this.aspectMetadata;
	}

	@Override
	@Nullable
	public 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;
		}
	}

	@Override
	public 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> ajTypes = 
			Collections.synchronizedMap(new WeakHashMap>());

		public static  AjType getAjType(Class fromClass) {
			WeakReference weakRefToAjType =  ajTypes.get(fromClass);
			if (weakRefToAjType!=null) {
				AjType theAjType = weakRefToAjType.get();
				if (theAjType != null) {
					return theAjType;
				} else {
					// 其实只有这一步操作:new AjTypeImpl~~~  AjTypeImpl就相当于代理了Class的很多事情~~~~
					theAjType = new AjTypeImpl(fromClass);
					ajTypes.put(fromClass, new WeakReference(theAjType));
					return theAjType;
				}
			}
			// neither key nor value was found
			AjType theAjType =  new AjTypeImpl(fromClass);
			ajTypes.put(fromClass, new WeakReference(theAjType));
			return theAjType;
		}
}


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


AjTypeImpl

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

public class AjTypeImpl implements AjType {
	private static final String ajcMagic = "ajc$";
	// 它真正传进来的,只是这个class,它是一个标注了@Aspect注解的Class类
	private Class 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 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 getJavaClass() {
		return clazz;
	}
	public AjType getSupertype() {
		Class superclass = clazz.getSuperclass();
		return superclass==null ? null : (AjType) 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 filteredMethods = new ArrayList();
		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 pointcuts = new ArrayList();
		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 name
				int 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 adviceList = new ArrayList();
		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(); }
}

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号