您的位置:首页 > 编程语言 > Java开发

Spring基于注解形式的 AOP的原理流程及源码解析(四)

2017-11-06 10:07 1026 查看
我们接着上篇博客继续讲。在上篇博客中,讲述的是正在实例化的Bean的beanClass和Spring容器内所有的切面Advisor进行匹配的过程。这个过程如果返回了匹配上的Advisor(一个或多个),则表明这个Bean应该被代理;如果返回的结果为空,则这个Bean不会被代理。

代码块1

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//如果这一步返回的结果不是空集合,则表明有匹配上的切面Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//对返回的切面集合做拓展
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//对切面集合做排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

protected void extendAdvisors(List<Advisor> candidateAdvisors) {
//将ExposeInvocationInterceptor.ADVISOR实例加入到切面集合的首位元素,这个元素在生成AOP对象是要用到
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}

}


AbstractAdvisorAutoProxyCreator有对切面排序的方法,不过其子类AspectJAwareAdvisorAutoProxyCreator重写了排序方法,正常应该调用其子类的方法

代码块2

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
//按Ordered接口及@Order的序号值来作为排序的准则
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
AnnotationAwareOrderComparator.sort(advisors);
return advisors;
}
}

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

private static final Comparator<Advisor> DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();

protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
//主要看DEFAULT_PRECEDE
4000
NCE_COMPARATOR它的排序规则
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
}
List<PartiallyComparableAdvisorHolder> sorted =
PartialOrder.sort(partiallyComparableAdvisors);
if (sorted != null) {
List<Advisor> result = new ArrayList<Advisor>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
else {
return super.sortAdvisors(advisors);
}
}
}


常量DEFAULT_PRECEDENCE_COMPARATOR是一个AspectJPrecedenceComparator对象,查看其排序的规则:

代码块3

class AspectJPrecedenceComparator implements Comparator<Advisor> {

private static final int HIGHER_PRECEDENCE = -1;
private static final int SAME_PRECEDENCE = 0;
private static final int LOWER_PRECEDENCE = 1;
public AspectJPrecedenceComparator() {
this.advisorComparator = AnnotationAwareOrderComparator.INSTANCE;
}

public int compare(Advisor o1, Advisor o2) {
//先根据@Order及Ordered的序号比较
int advisorPrecedence = this.advisorComparator.compare(o1, o2);
//如果没有这两个条件,返回的优先级相同,则按另一种规则比较
//Advisor实例是InstantiationModelAwarePointcutAdvisorImpl类型,所以declaredInSameAspect符合条件
if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) {
advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);
}
return advisorPrecedence;
}

private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) {
//看InstantiationModelAwarePointcutAdvisorImpl的determineAdviceType()方法
//@After,@AfterReturning,@AfterThrowing这三个注解是afterAdvice
boolean oneOrOtherIsAfterAdvice =
(AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
//Order按@Around, @Before, @After, @AfterReturning, @AfterThrowing的顺序
int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);

if (oneOrOtherIsAfterAdvice) {
// the advice declared last has higher precedence
//排序是对待织入一个Bean的多个切面进行排序,这些切面可能分布在不同的切面定义类里,也可能有多个切面定义在同一个类里
//afterAdvice有着比其他的advice更高的优先级,@After, @AfterReturning, @AfterThrowing这三个按倒序排列
//@Around, @Before这两个注解顺序排序,afterAdvice排在正常的advice前面
//排序后的顺序应该是:@AfterThrowing,@AfterReturning,@After,@Around,@Before
//顺序可能不正确,大家可以自己测试下,从代码上看是如此的
if (adviceDeclarationOrderDelta < 0) {
// advice1 was declared before advice2
// so advice1 has lower precedence
return LOWER_PRECEDENCE;
}
else if (adviceDeclarationOrderDelta == 0) {
return SAME_PRECEDENCE;
}
else {
return HIGHER_PRECEDENCE;
}
}
else {
// the advice declared first has higher precedence
if (adviceDeclarationOrderDelta < 0) {
// advice1 was declared before advice2
// so advice1 has higher precedence
return HIGHER_PRECEDENCE;
}
else if (adviceDeclarationOrderDelta == 0) {
return SAME_PRECEDENCE;
}
else {
return LOWER_PRECEDENCE;
}
}
}
}


接着上文将,合适的切面已经找到了,而且添加了一个头节点,对切面进行了排序,接下里就需要使用切面和Bean对象动态生成代理对象了:

代码块4

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//找到了合适的切面数组
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//开始创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}

ProxyFactory proxyFactory = new ProxyFactory();
//拷贝AOP配置,@EnableAspectJAutoProxy的proxyTargetClass值等
proxyFactory.copyFrom(this);

if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//如果有Advisor等类型的Bean,则实例化,加入Advisor数组,排在有注解生成的Advisor的前端
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}

proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}

return proxyFactory.getProxy(getProxyClassLoader());
}
}


通过代理工厂ProxyFactory生成代理实例:

代码块5

public class ProxyFactory extends ProxyCreatorSupport {

public Object getProxy(ClassLoader classLoader) {
//createAopProxy()一般生成ObjenesisCglibAopProxy实例
return createAopProxy().getProxy(classLoader);
}

public 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.");
}
//如果被代理的Class是一个接口,或者被代理类是一个Proxy代理生成的类,则生成JdkDynamicAopProxy(一般不会)
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}


接下去的就是通过Bean和Advisors生成代理对象了,很多都是CGLIB的代码,很晦涩麻烦,就不讲了。

接下来将一些通过CGLIB实现AOP的其他的知识点。

通过CGLIB生成的代理对象,持有原始Bean对象,同时继承自原始BeanClass

动态生成的对象的类名上含有 $$ 符号,所以判断一个对象是不是CGLIB生成的代理对象就看其类名上是否含有$$,详情看ClassUtils.isCglibProxy(Object)方法

当通过Advisors和Bean生成代理对象时,每一个Advisor会以MethodInterceptor的形式保存在代理对象中,每调用一个原始Bean的方法,均会触发所有的Advisor方法,而不仅仅是匹配注解表达式的方法,比如toString()

JDK Proxy生成的动态代理对象类名以Proxy$+数字组成,代理对象继承自Proxy对象,实现了被代理对象的接口。数字代表着是jdk动态代理生成的第几个代理对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 源码 aop