spring beanfactory的创建从这行命令开始:
ClassPathXmlApplicationContext ct=new ClassPathXmlApplicationContext("spring-config.xml");
public ClassPathXmlApplicationContext(...) {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
关键就是调用了refresh():
@Override
public void refresh() throws BeansException, IllegalStateException {
/**
* 加锁,说明并发执行,很多地方都有调用
* registerShutdownHook 也调用了
* close()方法也调有了,
* 容器在启动时,不能调Close的方法
*/
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/**
* 预初始化
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
/**
*
* 创建BeanFactory工厂,告诉子类去刷新内部BeanFactory,
* 加载Bean信息,并封装为BeanDefinition,并注册到BeanDefinitionRegistry
* key-value key :bean的id value就是BeanDefinition
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
/**
* 准备BeanFactory,进行一些设置
* Context的类加载器
*/
prepareBeanFactory(beanFactory);
try {
/**
* BeanFactory准备完成后,后置处理器增强,空方法
*/
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
/**
* 实例化实现了BeanFactoryPostProcessor接口的类中构造方法
* 并调用用postProcessBeanFactory 方法
*
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/**
*将实现了BeanPostProcessor的构造方法
*/
registerBeanPostProcessors(beanFactory);
/**
* 初始化国际华资源MessageSource组牛
*/
// Initialize message source for this context.
initMessageSource();
/**
* 初始化事件派发器
*/
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
/**
* 空方法
* 如果子类重写了这个方法就,调用子类重写的方法tomcat jetty之类的
*/
// Initialize other special beans in specific context subclasses.
onRefresh();
/**
* 注册应用监听器就是实现了ApplicationContextListener接口Bean
*/
// Check for listener beans and register them.
registerListeners();
/**
* 执行构造方法1
* setter方法2
* 实现了BeanNameAware接口的setBeanName方法3
* 实现了BeanFactoryAware接口的 setBeanFactory(BeanFactory beanFactory)方法4
* 实现了ApplicationContextAware接口的setsetApplicationContext 方法5
* 实现了BeanPostProcessor接口的postProcessBeforeInitialization方法6 ,AOP原理
* 标有PostConstruct注解的方法 7
* 实现了InitializingBean接口的afterPropertiesSet方法8
* 调用配置了init-method方法 9
* 实现了BeanPostProcessor接口的postProcessAfterInitialization方法 10
*
*/
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
/**
* 完成刷新Context,主要调用org.springframework.context.LifecycleProcessor接口onRefresh方法,发布事件ContextRefreshedEvent事件
*/
// Last step: publish corresponding event.
finishRefresh();
}
这些步骤就是工厂创建的全过程:
1.obtainFreshBeanFactory 创建bean工厂,同时解析xml配置文件,封装成document对象
2.prepareBeanFactory 初始化工厂,赋予属性值
3.postProcessBeanFactory --自定义扩展
4.invokeBeanFactoryPostProcesser–调用factory post process:
可以自定义对bean的元数据做一些修改和扩展
https://blog.csdn.net/baidu_19473529/article/details/81152109
https://blog.csdn.net/mn11201117/article/details/24986325?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.pc_relevant_is_cache&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.pc_relevant_is_cache
5.registerBeanPostProcesser --注册bean processer
6.initMessageSource --国际化处理
7.initApplicationEventMulticaster --初始化多播器,方便发布监听事件
8.registerListener --注册监听器(springboot,springmvc中会出现大量…)
9.finishBeanFactoryInitializetion —加载所有非懒加载的单列对象
流程图:
1.obtainFreshBeanFactory
1.0 主要作用作用
1.初始化 创建beanFactory
2.加载beanDefinition(该类封装了配置文件中bean的信息),并保存在factory中
…
1.1初始化
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
return this.getBeanFactory();
}
protected final void refreshBeanFactory() throws BeansException {
try {
//createFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
//定制factory ,就是设置了一些属性而已
this.customizeBeanFactory(beanFactory);
//加载beanDefinitions
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
}
1.2 BeanDefinition说明
什么是spring beanDefinition呢?一言概之就是把一个bean实例化出来的模型对象. 有人会问把一个bean实例化出来有Class就行了啊,Class也就是我们通常说的类对象,就是一个普通对象的建模对象,那么为什么spring不能用Class来建立bean呢?很简单,因为Class无法完成bean的抽象,比如bean的作用域,bean的注入模型,bean是否是懒加载等等信息,Class是无法抽象出来的,故而需要一个BeanDefinition类来抽象这些信息,以便于spring能够完美的实例化一个bean
上述文字可以简单理解spring当中的BeanDefinition就是java当中的Class
Class可以用来描述一个类的属性和方法等等其他信息
BeanDefintion可以描述springbean当中的scope、lazy,以及属性和方法等等其他信息
1.3 loadBeanDefinition
该函数的调用链非常麻烦,但目的是很明确的,就是加载配置文件中的bean信息,并封装成beanDfinitions,保存在factory的map结构中
private volatile List<String> beanDefinitionNames = new ArrayList(256); //存放bean的名称
//存放beanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
其调用过程的一系列操作如下:
resoucePath(String)->生成 resources(Resource)-> 生成 EncodedResource->获取inputstream,生成InputSource->根据inputSource和resource,生成document对象->生成BeanDefinitionParserDelegate,解析document->调用parseDefaultElement(),对配置文件中的各种信息进行处理:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, "import")) { this.importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, "alias")) { this.processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, "bean")) { this.processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, "beans")) { this.doRegisterBeanDefinitions(ele); } }
->processBeanDefinition ()–>registerBeanDefinition()
->最终生成beanDefinition,并放入map集合:
this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName);
2.postProcessBeanFactory
2.0主要作用
spring 留给用户的扩展,该方法在spring中并未被实现
3.invokeBeanFactoryPostProcessors
3.0 主要作用
1.调用用户自定义的postProcessBeanFactory,对bean的元数据进行扩展,
另外,我们有必要对postProcessBeanFactory接口以及BeanPostProcessor进行一个学习和比较
3.1.BeanPostProcessor接口
BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口。接口声明如下:
public interface BeanPostProcessor {
//bean初始化方法调用前被调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化方法调用后被调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
运行顺序
=Spring IOC容器实例化Bean=
=调用BeanPostProcessor的postProcessBeforeInitialization方法=
=调用bean实例的初始化方法=
=调用BeanPostProcessor的postProcessAfterInitialization方法=
实列
/**
* 后置处理器:初始化前后进行处理工作
* 将后置处理器加入到容器中
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
}
}
3.2postProcessBeanFactory与BeanPostProcessor的区别
简介:
bean工厂的bean属性处理容器,说通俗一些就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。
示例
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
int count = beanFactory.getBeanDefinitionCount();
String[] names = beanFactory.getBeanDefinitionNames();
System.out.println("当前BeanFactory中有"+count+" 个Bean");
System.out.println(Arrays.asList(names));
}
}
区别:
注册BeanFactoryPostProcessor的实例,需要重载
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
通过beanFactory可以获取bean的示例或定义等。同时可以修改bean的属性,这是和BeanPostProcessor最大的区别。
4.registerBeanPostProcessors
4.0 主要作用
注册用户自定义的beanPostProcessor,但是并未调用,是等到初始化bean的时候才会调用
5.initApplicationEventMulticaster
5.0 主要作用
1.初始化事件监听多路广播器,方便后续的监听器的注册,也即this.registerListeners();
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
....
} else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
.......
}
}
}
5.1 观察者模式
这一步骤初始化了applicationEventMulticaster,并在接下去的一个步骤(registerListeners)注册了监听器
实际上是用到了设计模式之观察者模式
如果你还不理解观察模式,请看:
回到该步骤中,当有事件触发时,applicationEventMulticaster会遍历订阅者,触发事件:
并且是将任务提交到线程池中进行的
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
Executor executor = this.getTaskExecutor();
Iterator var5 = this.getApplicationListeners(event, type).iterator();
while(var5.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var5.next();
if (executor != null) {
executor.execute(() -> {
//传播事件
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
6.finishBeanFactoryInitialization
6.0 主要作用
factory创建完毕,做一些末尾工作,
并开始加载单例bean,因为加载bean又是一个相当复杂的过程,我们放在下一篇文章讲解