这个类的设计,和Spring ioc的结合,简直是吊炸天,实现了根据配置把spring ioc里面的bean替换为相应的代理对象,也为AspectJ的整合提供了支持,让我们来看看Spring是如何做到这种更高级的声明式Aop
类结构
Spring Bean后处理器
阅读AbstractAutowireCapableBeanFactory的doCreateBean和destroyBean方法,我们能清楚看到Spring bean创建的整个生命周期,具体如下:
- 调用
InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
- bean实例化
- 调用
InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation(Object bean, String beanName)
- 调用
InstantiationAwareBeanPostProcessor的postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
- bean注入properties
- 分别调用BeanNameAware,BeanClassLoaderAware,BeanFactoryAware中的方法
- 调用
BeanPostProcessor的postProcessBeforeInitialization(Object bean, String beanName)
- 调用InitializingBean的afterPropertiesSet方法
- 调用自定义初始化方法
- 调用BeanPostProcessor的
postProcessAfterInitialization(Object bean, String beanName)
- 调用DisposableBean的
destroy()
方法 - 调用自定义销毁方法
下面分别介绍这三个bean后处理器的功能
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
从生命周期中可以看到,BeanPostProcessor中的这两个方法分别会在bean调用init方法前后回调,用于对已经注入properties的bean对象进行修改,把bean替换成代理对象会在postProcessAfterInitialization中执行
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
}
postProcessBeforeInstantiation和postProcessAfterInstantiation分别在bean实例化前后回调
postProcessPropertyValues将在注入properties之前触发,可以对整理好的properties进行修改
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException;
Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException;
Object getEarlyBeanReference(Object bean, String beanName) throws BeansException;
}
predictBeanType用于提前给出postProcessBeforeInstantiation生成的bean的类型
determineCandidateConstructors用于bean初始化的时候决定调用哪一个构造函数,如果针对某个类型的bean设置了这个回调,会采用回调设置的构造函数初始化bean,具体逻辑代码如下
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
getEarlyBeanReference用于解决循环依赖的问题
这三个bean后处理器讲解好了 ,现在我们开始讲DefaultAdvisorAutoProxyCreator是怎么实现自动配置代理对象的
DefaultAdvisorAutoProxyCreator
从类结构图中可以看到主要的继承链,DefaultAdvisorAutoProxyCreator->AbstractAdivisorAutoProxyCreator->AbstractAutoProxyCreator->ProxyProcessorSupport->ProxyConfig
ProxyConfig
public class ProxyConfig implements Serializable {
/** use serialVersionUID from Spring 1.2 for interoperability */
private static final long serialVersionUID = -8409359707199703185L;
// 如果该值为true,则proxyFactory将会使用CGLIB对目标对象进行代理,默认值为false
private boolean proxyTargetClass = false;
// 标记是否对代理进行优化。启动优化通常意味着在代理对象被创建后,增强的修改将不会生效,因此默认值为false。
private boolean optimize = false;
// 该属性用于空值生成的代理对象是否可以强制转型为Advised,默认值为false,表示任何生成的代理对象都可以强制转换成Advised,true是不可以,可以通过Adviced查询代理对象的一些状态
boolean opaque = false;
// 标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。
// 当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。
boolean exposeProxy = false;
// 标记该配置是否需要被冻结,如果被冻结,将不可以修改增强的配置。
// 如果该值为true,那么代理对象的生成的各项信息配置完成,则不容许更改,如果ProxyFactory设置完毕,该值为true,则不能对Advice进行改动,可以优化代理对象生成的性能。默认情况下该值为false
private boolean frozen = false;
...
}
ProxyProcessorSupport
看名字就知道是一个为代理生成提供支持的工具类,主要提供evaluateProxyInterfaces方法用来根据BeanClass对ProxyFactory中的代理方式进行配置,方法如下
/**
* This should run after all other processors, so that it can just add
* an advisor to existing proxies rather than double-proxy.
*/
private int order = Ordered.LOWEST_PRECEDENCE;
@Override
public int getOrder() {
return this.order;
}
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !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.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
proxyFactory.setProxyTargetClass(true);
}
}
这里会判断是否可以代理接口,如果可以,用proxyFactory的addInterface方法设置所有存在的接口类,如果不可以,那么调用setProxyTargetClass(true)
,配置为代理类
同时我们可以注意到这个类实现了Ordered接口,并且设置order = Ordered.LOWEST_PRECEDENCE,这是为了让生成代理的后处理器最后一个执行(原因可能是在之前的后处理器可能也会把Advisor加进去,那样就会出现不生效的问题)
AbstractAutoProxyCreator
这个类是这个继承链中最核心的类,因为生成代理的逻辑封装在这里
它实现SmartInstantiationAwareBeanPostProcessor,在回调方法里封装了把bean对象替换为代理对象的逻辑,在getEarlyBeanReference,postProcessBeforeInstantiation,postProcessAfterInitialization均能产生代理,postProcessBeforeInstantiation需要在配置了TargetSourceCreator之后才能生效,目前没有遇到这个场景,所以忽略,getEarlyBeanReference是为了解决循环依赖重写的,用来提前生成代理类,postProcessAfterInitialization在getEarlyBeanReference没有生效的情况下会被调用,这两个方法都调用了wrapIfNecessary来生成代理,我们来看下这个方法
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;
}
wrapIfNecessary首先会通过getAdvicesAndAdvisorsForBean得到拦截器集合,这个会交给子类实现,子类可以设计不同的策略来获取拦截器集合,如果getAdvicesAndAdvisorsForBean返回的集合不为空,就调用createProxy生成代理
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();
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());
}
createProxy还是比较熟悉的,在上节铺垫过,使用了ProxyFactory的编程式Aop生成代理。通过这几个回调,巧妙的在spring生命周期内把我们生成代理bean的行为注入了
AbstractAdvisorAutoProxyCreator
主要实现了AbstractAutoProxyCreator提供的扩展点方法getAdvicesAndAdvisorsForBean,用来设置拦截器集合
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
getAdvicesAndAdvisorsForBean中会通过findEligibleAdvisors来获取拦截器集合,如果不存在返回DO_NOT_PROXY,来看下findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}
在findEligibleAdvisors中,通过findCandidateAdvisors来获取候选的adivisors,内部使用了advisorRetrievalHelper.findAdvisorBeans,其实就是从beanfactory获取实现Advisor接口的bean,然后可以在这个方法里面看到
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
注意到有一个isEligibleBean方法,在AbstractAdivisorAutoProxyCreator使用了BeanFactoryAdvisorRetrievalHelper扩展子类,重定义了isEligibleBean方法,如下
private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {
public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
super(beanFactory);
}
@Override
protected boolean isEligibleBean(String beanName) {
return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
}
}
把BeanFactoryAdvisorRetrievalHelper中的isEligibleBean委托给了AbstractAdvisorAutoProxyCreator实现,AbstractAdvisorAutoProxyCreator中默认实现如下
protected boolean isEligibleAdvisorBean(String beanName) {
return true;
}
这个实现默认为不过滤,可以让子类去实现
DefaultAdvisorAutoProxyCreator
DefaultAdvisorAutoProxyCreator实现AbstractAdivisorAutoProxyCreator开放的扩展点isEligibleAdvisorBean,逻辑很简单,如下
protected boolean isEligibleAdvisorBean(String beanName) {
if (!isUsePrefix()) {
return true;
}
String prefix = getAdvisorBeanNamePrefix();
return (prefix != null && beanName.startsWith(prefix));
}
通过配置的prefix来过滤adivisor bean
InfrastructureAdvisorAutoProxyCreator
InfrastructureAdvisorAutoProxyCreator也实现了AbstractAdivisorAutoProxyCreator开放的扩展点isEligibleAdvisorBean
protected boolean isEligibleAdvisorBean(String beanName) {
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}
可以看到,这个过滤条件是,只选择框架级别(beanDefinitiod的role为ROLE_INFRASTRUCTURE)的Adivisor来进行对符合条件的对象进行织入,生成代理
总结
DefaultAdvisorAutoProxyCreator主要实现的功能为使用bean后处理器的回调函数,根据ioc容器配置的advisor,来对ioc 容器中的其他bean生成相应代理