ProxyFactoryBean
&AspectProxyFactory
分析
上篇使用ProxyCreatorSupport
的实现类ProxyFactory
结合案例剖析了SpringAop
原生方式底层运行原理。之前也提到了ProxyFactoryBean、AspectProxyFactory
和ProxyFactory
相比只是增加了一些feture
, 本节就来剖析下这两个实现类在原生的基础上做了哪些事情。
ProxyFactoryBean
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
......
//与ProxyFactory相比ProxyFactoryBean新增了interceptorNames这个属性
//该属性可以指定多个 Advice\Advisor\Interceptor类型的Bean的name
private String[] interceptorNames;
private boolean singleton = true;
private transient BeanFactory beanFactory;
private boolean advisorChainInitialized = false;
//保存ProxyFactoryBean#getObject返回的代理对象
private Object singletonInstance;
//之前文章遇到过这个AdvisorAdapterRegistry,将Advice包装为Advisor
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
@Override
@Nullable
public Object getObject() throws BeansException {
//初始化interceptorNames属性中指定的Advice、Advisor等Bean
initializeAdvisorChain();
if (isSingleton()) {
return getSingletonInstance(); //返回代理对象
}
else {
if (this.targetName == null) {
logger.info("Using non-singleton proxies with singleton targets is ...");
}
return newPrototypeInstance();
}
}
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//防止并发初始化AdvisorChain
if (this.advisorChainInitialized) {
return;
}
//如果interceptorNames属性有设置bean名称,则进行处理
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available ..."));
}
if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
throw new AopConfigException("Target required after globals");
}
//for循环处理指定的bean名称
for (String name : this.interceptorNames) {
//处理定义的模糊bean名称,例如 *Service
//这边会将匹配到的所有Bean包装为Advisor都添加进AdvisedSupport#advisors属性中
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors ...");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
else {//处理其他精确定义的Bean名称
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
//将获取到的Bean包装为Advisor
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
//该方法主要是根据interceptorNames属性获取到的Advice、Advisor类型的Bean
//将这些Bean统一包装为Advisor类型添加进AdvisedSupport#advisors属性中 (这个步骤和ProxyFactory中是一样的)
private void addAdvisorOnChainCreation(Object next, String name) {
Advisor advisor = namedBeanToAdvisor(next);
if (logger.isTraceEnabled()) {
logger.trace("Adding advisor with name '" + name + "'");
}
addAdvisor(advisor);
}
//使用AdvisorAdapterRegistry将Bean统一包装为Advisor
private Advisor namedBeanToAdvisor(Object next) {
try {
return this.advisorAdapterRegistry.wrap(next);
}
catch (UnknownAdviceTypeException ex) {
throw new AopConfigException("Unknown advisor type ....", ex);
}
}
//核心方法 : 生成代理类并返回
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
//实时获取目标对象实例
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine ...");
}
//获取目标对象的接口并设置到AdvisedSupport#interfaces属性中
//这个步骤和ProxyFactory中是一样的,用于保存代理接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
super.setFrozen(this.freezeProxy);
//生成代理类并返回
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
private TargetSource freshTargetSource() {
if (this.targetName == null) {
if (logger.isTraceEnabled()) {
logger.trace("Not refreshing target: Bean name not .....");
}
return this.targetSource;
}
else {
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available ....");
}
Object target = this.beanFactory.getBean(this.targetName);
return (target instanceof TargetSource ? (TargetSource) target : new SingletonTargetSource(target));
}
}
.......
}
如上是对ProxyFactoryBean
核心源码的分析,从分析中可以看出它和ProxyFactory
相比新增了一个interceptorNames
属性,该属性可以指定一个Advice或Advisor
类型的Bean
的bean名称
数组,ProxyFactoryBean#getObject()
方法会在生成目标对象的AOP
代理之前,先把这个属性中指定的bean名称对应的Bean
(Advisor
或者Advice
类型)使用DefaultAdvisorAdapterRegistry
统一将它们转为Advisor
类型后添加到之前分析过的AdvisedSupport#advisors
属性中。处理完interceptorNames
属性后就和ProxyFactory
的逻辑一样了 : 生成代理对象。
AspectJProxyFactory
AspectJProxyFactory
的逻辑比较多此处就不再贴代码了,总的来说可以分为以下步骤 :
- 首先将将切面中被
@Pointcut、@After、@Before、@AfterThrowing、@Around、@AfterReturning
注解修饰的方法包装为切点和相应类型的Advice
.如下图所示ReflectiveAspectJAdvisorFactory#getAdvice
方法是转Advice
的核心逻辑。@Pointcut
切点的解析也类似。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
......
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect");
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
......
}
-
第二步是将第一步中获取到的每个
Advice
和其切点组合成一个Advisor
(具体的Advisor
类型是InstantiationModelAwarePointcutAdvisorImpl
).这一步的具体逻辑可以参考AspectJProxyFactory#addAdvisorsFromAspectInstanceFactory
方法中的第一行代码,这行代码又将逻辑委托给了ReflectiveAspectJAdvisorFactory#getAdvisors
方法private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) { //获取到当前定义所有Advisor List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory); Class<?> targetClass = getTargetClass(); Assert.state(targetClass != null, "Unresolvable target class"); //从所有的Advisor中获取到需要对当前类拦截的Advisor advisors = AopUtils.findAdvisorsThatCanApply(advisors, targetClass); //向对当前类有效的Advisor列表表头添加ExposeInvocationInterceptor拦截器,下面会讲到 AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors); AnnotationAwareOrderComparator.sort(advisors); //将对当前类有效的Advisor添加到AdvisedSupport#advisors属性中,最后生成代理对象 addAdvisors(advisors); }
-
第三步是在第二步获取到的
List<Advisor>
基础上,向列表的头部添加一个ExposeInvocationInterceptor.ADVISOR
类型的Advisor
. 逻辑在上面所示的AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
中。这个Advisor
相当于是一个保存当前连接点MethodInvocation
信息的ThreadLocal
。 因为第一步获取到的各个Advice
在执行时需要使用连接点相关信息,所以ExposeInvocationInterceptor
的放在首位的目的就是供其他Advice
获取连接点信息。 -
第四步就和之前分析的
ProxyFactory
逻辑一样了 : 将第三步中的List<Advisor>
添加到AdvisedSupport#advisors
属性中,生成代理对象并返回。