额。。。终于艰难的把整个aop和部分ioc初始化过程捋了遍。。。
总结
1.在 bean初始化完成,加入到spring ioc容器之前,会调用BeanPostProcessors执行后置动作
2.其中会调用自动代理生成器(AbstractAutoProxyCreator)或者其他的自定义代理生成(AbstractAdvisingBeanPostProcessor子类)来判断(类、方法)、生成代理类,最后替换掉原来的bean放入到容器中
3.因此,通过ioc容器注入依赖的类,实际注入的是代理类(如果有的话),在调用代理类的时候,会被拦截(cglib的MethodInterceptor,jdk动态代理的InvocationHandler),调用Advisor方法
aop代理类的生成
总结
其实总的来说并不复杂,就是在初始化上下文加载bean的时候,判断该bean是否需要代理,如果需要则生成代理类,把代理类存放到容器中,然后需要注入该bean的时候,实际注入的是代理类
流程:
下面逐一讲解下各个流程
1.spring启动、初始化上下文
整个加载bean的过程基本是在AbstractApplicationContext#refresh方法中执行,然后在加载完BeanFactory,PostProcessors后,调用finishBeanFactoryInitialization来加载剩余bean,也就是我们定义的bean
public void refresh() throws BeansException, IllegalStateException {
...
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
...
}
2.bean的加载
DefaultListableBeanFactory#preInstantiateSingletons
AbstractBeanFactory#getBean
AbstractBeanFactory#doGetBean
DefaultSingletonBeanRegistry#getSingleton
AbstractAutowireCapableBeanFactory#createBean
AbstractAutowireCapableBeanFactory#doCreateBean
AbstractAutowireCapableBeanFactory#initializeBean
在经过一些列的方法后,终于把bean初始化完成(其中过程过于复杂。。。艰辛)
bean初始化完成后,调用AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization,其中会调用BeanPostProcessor#postProcessAfterInitialization对bean进行后置的处理
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
3.aop相关的BeanPostProcessor对bean进行处理
跟aop相关的BeanPostProcessor是AbstractAdvisingBeanPostProcessor其子类和AbstractAutoProxyCreator,这两类主要差别是在判断是否需要代理,换句话说,就是各自负责不同的类型的代理
3.1判断是否需要代理
总结
通过自动生成代理的走AbstractAutoProxyCreator,而一些需要特殊处理的走AbstractAdvisingBeanPostProcessor子类
都是通过判断类及所有方法是否有匹配的Advisor(根据Poincut带的ClassFilter和MethodMatcher),来决定是否需要代理
AbstractAutoProxyCreator
总结
核心方法是下面wrapIfNecessary中的getAdvicesAndAdvisorsForBean,会去根据bean的名字、类型去获取相应的通知,而这个方法在spring有2种实现(下图也可以看到druid自己实现来创建自己的代理类)
其中一种BeanNameAutoProxyCreator,是通过名字匹配(左右模糊、精确),功能比较简单
而另一种的AbstractAdvisorAutoProxyCreator,通过实现ClassFilter和MethodMatcher来实现各种的匹配方法(如:AnnotationMethodMatcher就用于AnnotationMatchingPointcut,针对注解的判断,@Async注解就是用的这个切面类)。平时手动创建的Pointcut等都是由该类处理
@Override
public Object postProcessAfterInitialization(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;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
// 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;
}
下面看下这两种不同的实现是怎样:
BeanNameAutoProxyCreator
其实从名字可以看出,大概就是通过名字来查询匹配,从下面核心匹配方法 isMatch 的注释可以看到,通过名字匹配,匹配规则是右模糊(xxx*)、左模糊(*xxx)、以及精确匹配(xxx),比较简单的一个匹配方法
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
if (this.beanNames != null) {
for (String mappedName : this.beanNames) {
if (FactoryBean.class.isAssignableFrom(beanClass)) {
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
continue;
}
mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
if (isMatch(beanName, mappedName)) {
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
BeanFactory beanFactory = getBeanFactory();
if (beanFactory != null) {
String[] aliases = beanFactory.getAliases(beanName);
for (String alias : aliases) {
if (isMatch(alias, mappedName)) {
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
}