BeanFactory
开胃菜:生成容器,充满bean对象的工厂
加载一些xml文件的beanDefinition时调用refreshBeanFactory(),但是加载的只是${db.username}这种值,所以需要进行替换,那么BeanFactoryPostProcessor进行处理
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 把xml文件加载进来,但是是原封不动的加载比如 ${db.username}这种属性,暂时还没处理
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
接着一直进入refresh()的invokeBeanFactoryPostProcessors(beanFactory)方法,属性值进行了替换。BeanFactoryPostProcessors是一个接口,实现了该接口的实现类,会被调用,无论是xml还是注解,其实都是实现了这个接口,根据不同的注解进行相应的解析,比如AutowiredAnnotationBeanPostProcessor,这个是注解@autoWried的具体实现。这样一来就可以修改BeanDefinition的属性。
Bean的生命周期
bean的生命周期也是和java的对象创建类似,java对象就是初始化,在堆中创建一个对象,但是是 空属性,后续进行赋值,或者是初始化方法生成一个完整的对象,而Bean也是类似有个生命周期
<li>BeanNameAware's {@code setBeanName}
* <li>BeanClassLoaderAware's {@code setBeanClassLoader}
* <li>BeanFactoryAware's {@code setBeanFactory}
* <li>EnvironmentAware's {@code setEnvironment}
* <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
* <li>ResourceLoaderAware's {@code setResourceLoader}
* (only applicable when running in an application context)
* <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* (only applicable when running in an application context)
* <li>MessageSourceAware's {@code setMessageSource}
* (only applicable when running in an application context)
* <li>ApplicationContextAware's {@code setApplicationContext}
* (only applicable when running in an application context)
* <li>ServletContextAware's {@code setServletContext}
* (only applicable when running in a web application context)
// 这个就是方法初始化前的增强器
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom init-method definition
// // 这个就是方法初始化后的增强器
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
简单一张图可以表示,最后有一个销毁过程没有表示出来
1、填充属性:set方法
2、aware方法:beanFactory和ApplicationContext的set方法交由invokeAwareMethods这个方法去调用,我们不需要在代码中显式调用,只需要实现beanFactoryAware和ApplicationContextAware的接口就行
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);
}
}
}
3、before的beanPostProcessor就是对实例化之后的空对象进行功能增强的,底层采用的是aop的原理,before的话应该是啥事没干,但是在after里做了增强功能的事情
4、这样就在创建一个可以进行调用的bean对象
重点:容器和对象的创建流程
1、先创建容器
2、加载配置文件,封装成beanDefinition
3、调用执行InvokeBeanFactoryPostProcessor
准备工作(重点就是refresh方法,对应13个方法):
准备beanPostProcessor
准备监听器,事件,广播
4、实例化
5、初始化
6、获取完整对象
bean对象的作用域默认是单例,
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
.......
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
接着准备获取bean对象,但是目前容器里还没有这个bean对象
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
接着进入创建对象的流程,而spring创建对象的方式就是采用反射的方式
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
但是一直到反射结束,这个对象只是一个空对象,没有任何属性的,当真正调用popularBean的时候,才会进行赋属性。
接着调用initlizeBean初始化方法method,执行aware接口,初始化了beanFactory,而ApplicationContext不会设置
虽然ApplicationContext继承了beanFactory,但实际是两条不同的线。