spring启动

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版权协议,转载请附上原文出处链接和本声明。