Spring初始化
--- StandardContext --- //org.apache.catalina.core.StandardContext
startInternal -> listenerStart -> listener.contextInitialized(ServletContextListener.contextInitialized)
--- ContextLoaderListener ---
contextInitialized -> initWebApplicationContext -> createWebApplicationContext(Default:XmlWebApplicationContext) -> configureAndRefreshWebApplicationContext -> refresh
--- AbstractApplicationContext ---
refresh
//1.create factory and load bean definition.
obtainFreshBeanFactory
-> refreshBeanFactory
-> createBeanFactory(DefaultListableBeanFactory)
-> loadBeanDefinitions //加载applicationContext文件,将里面的bean定义转成BeanDefinition,装在到BeanFactory beanDefinitionMap
//2.invoke factory processor: Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors
-> postProcessBeanFactory //BeanFactoryPostProcessor,可以修改bean definitions,此动作在所有bean初始化之前 //All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans.
//3.register bean processor: Register bean processors that intercept bean creation. 将BeanPostProcessor类型的bean提前加载、实例化初始化,并注册,然后在第4步普通bean创建时执行拦截方法:postProcessBefore/AfterInitialization
registerBeanPostProcessors
-> registerBeanPostProcessors
-> getBean (for (String ppName : postProcessorNames); BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);) //go to AbstractBeanFactory.getBean getBean这里会实例化BeanPostProcessor
-> beanFactory.addBeanPostProcessor(postProcessor);
//4.instantiate: Instantiate all remaining (non-lazy-init) singletons. 实例化剩余普通的bean
finishBeanFactoryInitialization(beanFactory);
-> preInstantiateSingletons(beanFactory.preInstantiateSingletons()) //List beanNames = new ArrayList(this.beanDefinitionNames); for (String beanName : beanNames) -> getBean(beanName);
-> getBean (for (String beanName : beanNames) { getBean(beanName); }) //go to AbstractBeanFactory.getBean
扩展
扩展原理:
1、init,registerBeanDefinitionParser注册BeanDefinition解释器
2、parse:2.1.element 获取自定义的配置 2.2.registerBeanDefinition 向registry注册BeanDefinition
registry其实就是factory:DefaultListableBeanFactory,registerBeanDefinition 注册beanDefinition,后续在finishBeanFactoryInitialization中会遍历所有beanDefinition进行实例化。
这个注册过程其实就跟手动注解@Component一个意思,注册beanDefinition,之后由工厂进行初始化。
--- AbstractXmlApplicationContext ---
loadBeanDefinitions -> XmlBeanDefinitionReader.loadBeanDefinitions -> DefaultBeanDefinitionDocumentReader.registerBeanDefinitions
-> DefaultBeanDefinitionDocumentReader.parseBeanDefinitions -> BeanDefinitionParserDelegate.parseCustomElement
--- BeanDefinitionParserDelegate ---
parseCustomElement -> resolve(String namespaceUri) -> namespaceHandler.init() //NamespaceHandlerSupport -> registerBeanDefinitionParser("xx",new XXBeanDefinitionParser());
-> handler.parse -> XXBeanDefinitionParser.parse -> registry.registerBeanDefinition("xxBeanDefinition",xxBeanDefinition);//解析自定义的配置文件,然后一般会向registry进行注册registerBeanDefinition
通过NamespaceHandlerSupport、BeanDefinitionParser完成扩展:
public class XXNamespaceHandler extends NamespaceHandlerSupport{
@Override
public void init() {
registerBeanDefinitionParser("annotation-driven",new XXBeanDefinitionParser());
}
}
//XXBeanDefinitionParser 也可以继承自AbstractSingleBeanDefinitionParser、AbstractBeanDefinitionParser,原理是类似的。
public class XXBeanDefinitionParser implements BeanDefinitionParser{
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//element 配置文件的对象
RootBeanDefinition xxBeanDefinition = new RootBeanDefinition();
BeanDefinitionRegistry registry = parserContext.getRegistry();
registry.registerBeanDefinition("xxx", xxBeanDefinition);
return xxBeanDefinition;
}
}
创建Bean
//Parse the elements at the root level in the document: "import", "alias", "bean".
--- AbstractBeanFactory ---
getBean
doGetBean
getSingleton
createBean //go to AbstractAutowireCapableBeanFactory.createBean
--- AbstractAutowireCapableBeanFactory ---
createBean
-> resolveBeforeInstantiation -> postProcessBeforeInstantiation (if (bean != null) -> postProcessAfterInitialization)
-> doCreateBean
-> createBeanInstance -> instantiateBean -> BeanUtils.instantiateClass(constructorToUse) -> constructorToUse.newInstance(args)
-> populateBean(postProcessAfterInstantiation -> autowire -> postProcessPropertyValues -> applyPropertyValues)
-> initializeBean
-> invokeAwareMethods(BeanNameAware->setBeanName, BeanClassLoaderAware->setBeanClassLoader, BeanFactoryAware->setBeanFactory)
-> postProcessBeforeInitialization
-> invokeInitMethods(afterPropertiesSet&invokeCustomInitMethod)
-> postProcessAfterInitialization
Bean创建关键流程如下:
createBean
-> postProcessBeforeInstantiation -> return null -> createBeanInstance -> postProcessAfterInstantiation -> postProcessBeforeInitialization -> invokeInitMethods -> postProcessAfterInitialization -> return bean
-> postProcessBeforeInstantiation -> not null -> postProcessAfterInitialization -> return bean
从这里看可以看到,在这个过程有多个可以执行拦截的地方,这些拦截也正是Spring作为一个框架的优秀之处,因为在拦截的地方可以进行各种增强,使得其拥有良好的扩展性:
InstantiationAwareBeanPostProcessor: postProcessBeforeInstantiation/postProcessAfterInstantiation/postProcessPropertyValues 作用于实例化阶段
BeanPostProcessor: postProcessBeforeInitialization/postProcessAfterInitialization 作用于初始化阶段
1、createBean
1.1 resolveBeforeInstantiation
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); //applyBeanPostProcessorsBeforeInstantiation
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); //applyBeanPostProcessorsAfterInitialization
}
...
return bean;
1.2 applyBeanPostProcessorsBeforeInstantiation
//invoking their postProcessBeforeInstantiation methods. 调用postProcessBeforeInstantiation,这个方法在bean实例化之前执行
//Any returned object will be used as the bean instead of actually instantiating the target bean.
//A null return value from the post-processor will result in the target bean being instantiated.
//若返回了非空对象,则直接被当做bean,替代后续真正实例化的bean;若返回是空的,将继续调用实际的实例化方法
//即若在这里执行拦截返回了非空对象,后续bean的实例化将跳过,直接跳转执行bean的初始化后置操作postProcessAfterInitialization,然后直接返回
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); //InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
return null;
2、doCreateBean
2.1 createBeanInstance(beanName, mbd, args); //创建对象(实例化)
2.2 populateBean(beanName, mbd, instanceWrapper); //填充对象属性
2.3 initializeBean //初始化
2.2 populateBean
2.2.1 postProcessAfterInstantiation
//This is the ideal callback for performing field injection on the given bean instance. 是一个执行字段注入的回调方法。若返回false,将不再执行后续的字段注入。
//如果返回false,将不再给bean设置属性。此接口目前三个实现都是无任何操作,仅仅只是返回了true。
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
if (!continueWithPropertyPopulation) {
return;
}
2.2.2 autowire
PropertyValues pvs = mbd.getPropertyValues();
autowireByName(beanName, mbd, bw, newPvs); //加载属性依赖的bean
autowireByType(beanName, mbd, bw, newPvs);
2.2.3 postProcessPropertyValues
//Post-process the given property values before the factory applies them to the given bean. Also allows for replacing the property values to apply
//对属性值进行后置处理,允许替换要应用的属性值
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
2.2.4 applyPropertyValues
2.3 initializeBean
2.3.1 invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
2.3.2 applyBeanPostProcessorsBeforeInitialization //postProcessBeforeInitialization
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
2.3.3 invokeInitMethods //afterPropertiesSet, invokeCustomInitMethod
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean...) {
((InitializingBean) bean).afterPropertiesSet();
}
invokeCustomInitMethod
2.3.4 applyBeanPostProcessorsAfterInitialization
result = beanProcessor.postProcessAfterInitialization(result, beanName);
AOP
核心:AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor, InstantiationAwareBeanPostProcessor,
BeanPostProcessor
原理:postProcessBefore/AfterInstantiation, postProcessBefore/AfterInitialization,在Bean的创建或初始化的前后拦截,实现代理。
核心类:AbstractAutoProxyCreator、AnnotationAwareAspectJAutoProxyCreator
1、配置AspectJ:若需要AspactJ支持,需要添加配置,其实现对应 AnnotationAwareAspectJAutoProxyCreator,添加配置有2中方式
1.1 配置文件文件
1.2 AopConfigUtils
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary
2、构建Advisor
AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
2.1 postProcessBeforeInstantiation 以这个方法为入口构建Advisor(但这里并没有做拦截)
//AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { //Advisor所在的类跳过,不执行拦截
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //其他类执行代理创建,一般未指定targetSource,这里都不会执行代理创建
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null; //未自定义TargetSource的,一般也直接返回null
}
//AspectJAwareAdvisorAutoProxyCreator
protected boolean shouldSkip(Class> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List candidateAdvisors = findCandidateAdvisors(); //这里会去查找所有的Advisor,即找到所有增强方法
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) { //Advisor所在的类跳过,不执行拦截
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
2.2 Advisor的构造过程
2.2.1 查找所有bean,找出@Aspect切面的bean
buildAspectJAdvisors - BeanFactoryAspectJAdvisorsBuilder
for (String beanName : beanNames) {
if (this.advisorFactory.isAspect(beanType)) { //isAspect: hasAspectAnnotation(clazz) && !compiledByAjc(clazz)
List classAdvisors = this.advisorFactory.getAdvisors(factory);
}
}
2.2.2 找到所有的Advisor方法
getAdvisors - ReflectiveAspectJAdvisorFactory
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
//获取所有方法,排除Pointcut注解的方法
private List getAdvisorMethods(Class> aspectClass) {
final List methods = new LinkedList();
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
Collections.sort(methods, METHOD_COMPARATOR);
return methods;
}
2.2.3 找到带@Around @Before等注解的方法,并将其包装成Advisor
getAdvisor -> getPointcut -> findAspectJAnnotationOnMethod
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
protected static AspectJAnnotation> findAspectJAnnotationOnMethod(Method method) {
Class>[] classesToLookFor = new Class>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class> c : classesToLookFor) {
AspectJAnnotation> foundAnnotation = findAnnotation(method, (Class) c); //获取PointCut配置,如@Around("execution(* com.xx.xx.x..*.*(..)) || @annotation(com.xx.xx.xx.XXAnnotation)")
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
3.3 代理的创建 postProcessAfterInitialization
再回顾一遍这个流程:
refresh -> finishBeanFactoryInitialization -> preInstantiateSingletons -> getBean -> doGet.. -> createBean .. -> createBeanInstance(AbstractAutowireCapableBeanFactory) 这里就已经实例化完成,bean已经创建了 -> populateBean
-> initializeBean -> applyBeanPostProcessorsAfterInitialization -> beanProcessor.postProcessAfterInitialization(AnnotationAwareAspectJAutoProxyCreator)
-> postProcessAfterInitialization(AbstractAutoProxyCreator) -> wrapIfNecessary -> getAdvicesAndAdvisorsForBean(查找当前bean是否需要增强) -> AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)
-> createProxy -> proxyFactory.getProxy -> createAopProxy(DefaultAopProxyFactory) -> getProxy (CglibAopProxy)
真正代理创建并不是在postProcessBeforeInstantiation,而是postProcessAfterInitialization,所以真正拦截,将bean替换成代理对象是在postProcessAfterInitialization方法做的。
postProcessAfterInitialization 一般的实现,如果不做代理,就直接返回bean 就可以。
wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (specificInterceptors != DO_NOT_PROXY) {
Object proxy = createProxy;
return proxy; //返回的代理对象替换真正的bean
}
return bean;
}
DefaultAopProxyFactory
createAopProxy:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { //指定了proxy-target-class=true,或hasNoUserSuppliedProxyInterfaces 即当前类没有实现接口,则使用cglib
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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config); //cglib
}
else {
return new JdkDynamicAopProxy(config); //jdk
}
}
CglibAopProxy
getProxy
Enhancer enhancer = createEnhancer();
enhancer.setSuperclass(proxySuperClass); //targetClass
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
createProxyClassAndInstance