sping 启动
加载spring.xml文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
刷新
refresh();
刷新具体实现
public void refresh() throws BeansException, IllegalStateException {
// synchronized块锁(monitorenter --monitorexit),不然 refresh() 还没结束,又来个启动或销毁容器的操作
synchronized (this.startupShutdownMonitor) {
//一、【准备刷新】【Did four things】
prepareRefresh();
// 二、【获得新的bean工厂】关键步骤
//1、关闭旧的 BeanFactory
//2、创建新的 BeanFactory(DefaluListbaleBeanFactory)
//3、解析xml/加载 Bean 定义、注册 Bean定义到beanFactory(未初始化)
//4、返回全新的工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//三、【准备bean工厂】为BeanFactory配置容器特性,例如类加载器、表达式解析器、注册默认环境、后置管理器
prepareBeanFactory(beanFactory);
try {
// 四、【后置处理器Bean工厂】此处为空方法,子类的实现
postProcessBeanFactory(beanFactory);
//五、【调用bean工厂后置处理器】,开始调用我们自己实现的接口
//目标:
//调用顺序一:先执行bean定义注册(BeanDefinitionRegistryPostProcessor)的后置处理器
//调用顺序二:后执行bean工厂(BeanFactoryPostProcessor)的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
//六、【注册bean后置处理器】只是注册,但是不会反射调用
//逻辑:找出所有实现BeanPostProcessor接口的类,分类、排序、注册
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//七、【初始化消息源】国际化问题i18n,参照https://nacos.io/
initMessageSource();
// Initialize event multicaster for this context.
//八、【初始化应用程序事件多路广播】初始化自定义的事件监听多路广播器,(观察者)S
initApplicationEventMulticaster();
// 九、【刷新】具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前),此方法为空
onRefresh();
//十、【注册所有监听器】,监听器需要实现 ApplicationListener 接口。
registerListeners();
//十一、 【完成bean工厂初始化操作】
//1、初始化所有的 singleton beans,反射生成对象/填充
//2、 开始调用Bean的前置处理器和后置处理器
//目标:找到xxxx.newInstance!!!!!
//参照:com.spring.test.reflect.Test
finishBeanFactoryInitialization(beanFactory);
// 十二、发布事件与清除上下文环境
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 销毁已创建的Bean、以免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
// 取消refresh操作,重置容器的同步标识。
cancelRefresh(ex);
// 把异常往外抛
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//十三、重设公共缓存
resetCommonCaches();
}
}
}
下面具体讲解上面方法中的实现
一、invokeBeanFactoryPostProcessors(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
//调用顺序一:先执行bean定义注册(BeanDefinitionRegistryPostProcessor)的后置处理器
//调用顺序二:后执行bean工厂(BeanFactoryPostProcessor)的后置处理器
具体使用如下
//1.BeanDefinitionRegistryPostProcessor 实现了 BeanFactoryPostProcessor,postProcessBeanDefinitionRegistry()方法是BeanDefinitionRegistryPostProcessor类的方法,postProcessBeanFactory()是BeanFactoryPostProcessor类的方法
//2.在invokeBeanFactoryPostProcessors()中执行BeanDefinitionRegistryPostProcessor时按照排序执行 先后顺序如下,实现PriorityOrdered > 实现Ordered > 没实现的
//3.实现了BeanDefinitionRegistryPostProcessor,BeanFactoryPostProcessor 看名字就知道一个是对bd的修改,一个是对beanFactory的修改,修改时机比较早。
public class RedisConfig implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 新增
BeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClassName("com.jiumozhi.spring.annotation.Student");
registry.registerBeanDefinition("student",bd);
// 查询和修改
BeanDefinition student = registry.getBeanDefinition("student");
// 删除
registry.removeBeanDefinition("student");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
@Override
public int getOrder() {
return 1;
}
二、 registerBeanPostProcessors(beanFactory);
//【注册bean后置处理器】只是注册,但是不会反射调用.真正的调用在bean初始化前后
//逻辑:找出所有实现BeanPostProcessor接口的类,分类、排序、注册
三、initApplicationEventMulticaster()
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//如果已经有名字是"applicationEventMulticaster"的bean,就用这个
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
}
else {
//否则用SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
//以单例方式注册到bean工厂里
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
四、registerListeners()注册所有的监听器,发布是在最后的finishRefresh()中调用
//目标:查找所有实现了ApplicationListener,然后进行注册
//1、去集合applicationListeners查找
//2、去bean工厂找到实现ApplicationListener接口的bean
//3、去this.earlyApplicationEvents;在prepareRefresh()中this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners)添加的
protected void registerListeners() {
// 去集合applicationListeners查找;找到实现ApplicationListener的bean
for (ApplicationListener<?> listener : getApplicationListeners()) {
//增加监听
getApplicationEventMulticaster().addApplicationListener(listener);
}
//在去bean工厂找到实现ApplicationListener接口的bean
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
//增加监听
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//this.earlyApplicationEvents在prepareRefresh()添加的,如果有,就广播出去
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
示例:
Spring的事件监听主要涉及三个角色:
1)事件:ApplicationEvent抽象类的继承者;
2)事件发布者:事件多播器ApplicationEventMulticaster接口的实现类,比如SimpleApplicationEventMulticaster;
3)事件监听器:ApplicationListener 接口的实现类。
registerListeners方法主要将实现监听器接口(即ApplicationListener接口)的bean们注册到多播器中,即存储到applicationListenerBeans集合中。
Spring提供了很多内置事件,这里以ContextRefreshedEvent举例说明。ContextRefreshedEvent是ApplicationEvent继承者,,当ApplicationContext被初始化或刷新时,会触发ContextRefreshedEvent事件。
ContextRefreshedEvent源码:
public class ContextRefreshedEvent extends ApplicationContextEvent {
public ContextRefreshedEvent(ApplicationContext source) {
super(source);
}
}
自定义监听器:
public class LearnListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 打印容器中出事Bean的数量
System.out.println("监听器获得容器中初始化Bean数量:" + event.getApplicationContext().getBeanDefinitionCount());
String[] names = event.getApplicationContext().getBeanDefinitionNames();
for (String name : names){
System.out.println(name);
}
}
}
修改配置文件:
<bean id="learnListener" class="com.service.LearnListener"/>
启动类:
public class BeanLifeCycle{
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
ApplicationContext factory = new ClassPathXmlApplicationContext("beans.xml");
//触发监听器
((ClassPathXmlApplicationContext) factory).refresh();
((ClassPathXmlApplicationContext) factory).close();
}
}
日志:
监听器获得容器中初始化Bean数量:4
监听器获得容器中初始化Bean数量:4
从日志上看,监听器的onApplicationEvent方法被调用了2次,因为刷新方法refresh()被调用了2次。第一次是在容器初始化中,Spring自身调用refresh()方法。第二次是在代码中手动调用refresh()方法。
自定义事件监听
public class MyApplicationEvent extends ApplicationEvent {
//公共变量,存储消息
private Object meg;
//构造函数
public MyApplicationEvent(Object source, Object meg) {
super(source);
this.meg = meg;
System.out.println("事件发生了改变:" + meg);
}
//获取消息
public Object getMeg() {
return meg;
}
}
自定义监听器:
public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> {
//构造函数
public MyApplicationListener() {
}
@Override
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println("事件监听器收到消息: " + event.getMeg());
}
}
添加bean
<bean id="learnListener" class="com.service.MyApplicationListener"/>
启动类
public class BeanLifeCycle{
public static void main(String[] args) {
ApplicationContext factory = new ClassPathXmlApplicationContext("beans.xml");
MyApplicationEvent myApplicationEvent = new MyApplicationEvent(factory, "Event changes!");
//发布事件
factory.publishEvent(myApplicationEvent);
((ClassPathXmlApplicationContext) factory).close();
}
}
日志
事件发生了改变:Event changes!
事件监听器收到消息Event changes!
五、finishBeanFactoryInitialization(beanFactory)
初始化所有的单例bean,反射生成对象/填充属性
初始化bean,调用前后置处理器
实例化所有单例bean
beanFactory.preInstantiateSingletons();
具体实现
//1、实例化(反射)
//2、填充
//3、调用前置、后置处理器
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// this.beanDefinitionNames!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 触发所有的非懒加载的 singleton beans 的初始化操作
for (String beanName : beanNames) {
// 返回:Root bean: class [com.spring.test.impl.UserServiceImpl];
//scope=singleton; abstract=false; lazyInit=false;
//autowireMode=0。。。。。。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、非懒加载的、和singletons。如果配置了 'abstract = true',那是不需要初始化的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 处理 FactoryBean,此处不是工厂bean
if (isFactoryBean(beanName)) {
// FactoryBean 话,在 beanName 前面加上 ‘&’ 符号。再调用 getBean,getBean
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
// 判断当前 FactoryBean 是否是 SmartFactoryBean 的实现,此处忽略,直接跳过
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) () ->
((SmartFactoryBean<?>) factory).isEagerInit(),
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
} else {
// 调用前置后置处理器+实例化+填充+反射
//getBean---doGetBean---createBean---doCreateBean
//两大处调用:
// 1、从 BeanFactory 中获取一个 Bean
// 2、ioC容器初始化调用(先方法5:反射Bean工厂处理器;后方法11实例化)
//生成代理的时候是从方法11开始
getBean(beanName);
}
}
}
// 到这里说明所有的 ingleton beans 已经完成了初始化
// 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调,忽略
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
上面代码的大致意思 循环所有的beanNames,调用getBean(beanName)方法,完成bean初始化
版权声明:本文为itchenguang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。