上一篇文章说完了applyBeanPostProcessorsBeforeInitialization
,那么这篇文章说下applyBeanPostProcessorsAfterInitialization
,也就是在Bean初始化完,调用的后置处理器。
applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 同样获取createBean 过程中所有 BeanPostProcessors(bean后置处理器)
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 重点 :如果bean被子类标识为代理,则使用配置的拦截器创建一个代理。
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 重点
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary
如果给定的bean符合被代理的条件,就将其包装起来。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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.
// 获取代理类,如果存在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;
}
getAdvicesAndAdvisorsForBean
方法最终会调用AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
方法:
findEligibleAdvisors
查找所有适合自动代理此类的合格advisor。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 重点:查找自动代理中要使用的所有advisor。
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 重点:在获取到的所有Advisor中,查找可应用于指定bean的所有顾问。
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
findCandidateAdvisors()
该方法获取所有使用@Advisor的类,所以最终调用方法为:
advisors.add(this.beanFactory.getBean(name, Advisor.class));
这个就不细说了。
findAdvisorsThatCanApply
筛选bean。获取用于指定bean的
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 重点:调用AopUtils,
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
findAdvisorsThatCanApply
查找返回适用于给定类的 candidateAdvisors 列表的子列表。
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 重点,canApply方法
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
遍历被代理类的所有的方法,跟进切面表达式进行匹配,如果有一个方法匹配到,也就意味着该类会被代理。
匹配方法是借助org.aspectj.weaver.internal.tools实现,也就是AspectJ框架中的工具类,有兴趣的可以自行查看。
createProxy
获取给定bean
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
getProxy
getProxy
最终会调用DefaultAopProxyFactory#createAopProxy
方法
所以:
@Override
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.");
}
// //如果代理目标是接口或者Proxy类型,则走jdk代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
该方法通过三个变量来进行筛选代理方法:
- optimize:官方文档翻译为设置代理是否应执行积极的优化,默认为false。
- proxyTargetClass:这个在上面已经提到了,AopAutoConfiguration中指定,默认为true,也就是选择使用 cglib 代理。可以看到该变量和optimize意义一样,之所以这么做,个人理解是为了可以在不同的场景中使用。
- hasNoUserSuppliedProxyInterfaces:是否设置了实现接口。
hasNoUserSuppliedProxyInterfaces方法
确定提供的 advisedsupport 是否指定了 org.springframework.aop.springproxy接口(或者根本没有指定代理接口)。
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
UML图:
流程图:
总结
相对于前置处理,后置处理就要简单很多了
- 返回是否要代理给定的bean、要应用的附加建议(例如AOP联盟拦截器)和顾问。
- 创建代理类。