正文
- public void refresh() throws BeansException, IllegalStateException {
- synchronized(this.startupShutdownMonitor) {
- // 1. 初始化前的预处理
- this.prepareRefresh();
- // 2. 刷新Bean工厂
- ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
- // 3. BeanFactory的预处理配置
- this.prepareBeanFactory(beanFactory);
- try {
- // 4. BeanFactory的后置处理
- this.postProcessBeanFactory(beanFactory);
- // 5. 执行BeanFactory后置处理器
- this.invokeBeanFactoryPostProcessors(beanFactory);
- // 6. 注册Bean的后置处理器
- this.registerBeanPostProcessors(beanFactory);
- // 7. 初始化MessageSource
- this.initMessageSource();
- // 8. 初始化事件派发器
- this.initApplicationEventMulticaster();
- // 9. 子类的多态onRefresh
- this.onRefresh();
- // 10. 注册监听器
- this.registerListeners();
- // 11. 初始化所有剩下的单例Bean
- this.finishBeanFactoryInitialization(beanFactory);
- // 12. 完成容器的创建工作
- this.finishRefresh();
- } catch (BeansException var9) {
- if (this.logger.isWarnEnabled()) {
- this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
- }
- this.destroyBeans();
- this.cancelRefresh(var9);
- throw var9;
- } finally {
- // 13. 清除缓存
- this.resetCommonCaches();
- }
- }
- }
一、prepareRefresh:初始化前的预处理
- protected void prepareRefresh() {
- //设置容器启动时间
- this.startupDate = System.currentTimeMillis();
- //设置容器关闭状态为false
- this.closed.set(false);
- //设置容器激活状态为true
- this.active.set(true);
- if (this.logger.isDebugEnabled()) {
- if (this.logger.isTraceEnabled()) {
- this.logger.trace("Refreshing " + this);
- } else {
- this.logger.debug("Refreshing " + this.getDisplayName());
- }
- }
- //1.1初始化属性资源
- this.initPropertySources();
- //1.2校验
- this.getEnvironment().validateRequiredProperties();
- this.earlyApplicationEvents = new LinkedHashSet();
- }
1.1初始化属性值
初始化方法是个模压方法,由子类重写
- protected void initPropertySources() {
- }
Web容器GenericWebApplicationContext重写了此方法
- protected void initPropertySources() {
- //获取环境信息
- ConfigurableEnvironment env = getEnvironment();
- //判断是否是web配置环境
- if (env instanceof ConfigurableWebEnvironment) {
- ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
- }
- }
最终由StandardServletEnvironment进行初始化
- public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
- //使用web容器工具初始化
- WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
- }
把 Servlet 的一些初始化参数放入IOC容器中
- public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
- Assert.notNull(sources, "'propertySources' must not be null");
- String name = "servletContextInitParams";
- if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
- sources.replace(name, new ServletContextPropertySource(name, servletContext));
- }
- name = "servletConfigInitParams";
- if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
- sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
- }
- }
1.2属性校验
通过占位符解析器校验资源集合
- public void validateRequiredProperties() throws MissingRequiredPropertiesException {
- this.propertyResolver.validateRequiredProperties();
- }
这里的解析器作为常量在环境被实例化时就被创建出来的,PropertySourcesPropertyResolver是占位符解析器,将数据源中占位符替换成目标值

校验是否有需要被占位符修饰的属性,如果有但是资源中找不到对应属性的key就会抛出异常
- public void validateRequiredProperties() {
- MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
- for (String key : this.requiredProperties) {
- if (this.getProperty(key) == null) {
- ex.addMissingRequiredProperty(key);
- }
- }
- if (!ex.getMissingRequiredProperties().isEmpty()) {
- throw ex;
- }
- }
案例: 资源文件
- name=zhansan
- age=${name},10
- encoding=utf-8
- name2=${name}
测试代码
- @Test
- public void test1() throws Exception {
- //省略propertySources
- PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(getPropertySources());
- System.out.println(propertyResolver.getProperty("age"));
- System.out.println(propertyResolver.getProperty("encoding"));
- System.out.println(propertyResolver.resolvePlaceholders("must be encoding ${encoding}")); //输出must be encoding gbk
- }
输出结果
10,zhansan
utf-8
must be encoding utf-8
二、obtainFreshBeanFactory:刷新Bean工厂
- protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
- //2.1刷新Bean工厂
- refreshBeanFactory();
- return getBeanFactory();
- }
将容器刷新标识改为true,并且设置了工厂序列化id
- protected final void refreshBeanFactory() throws IllegalStateException {
- if (!this.refreshed.compareAndSet(false, true)) {
- throw new IllegalStateException(
- "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
- }
- this.beanFactory.setSerializationId(getId());
- }
三、prepareBeanFactory:Bean工厂预处理
- protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
- // 设置BeanFactory的类加载器、表达式解析器等
- beanFactory.setBeanClassLoader(getClassLoader());
- beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
- beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
- // 3.1 添加Aware执行器
- beanFactory.addBeanPostProcessor(new ApplicationContextDProcessor(this));
- beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
- beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
- beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
- beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
- beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
- beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
- // 3.2 自动注入的支持
- beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
- beanFactory.registerResolvableDependency(ResourceLoader.class, this);
- beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
- beanFactory.registerResolvableDependency(ApplicationContext.class, this);
- // 3.3 添加监听器执行器
- beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
- // Detect a LoadTimeWeaver and prepare for weaving, if found.
- if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
- beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
- // Set a temporary ClassLoader for type matching.
- beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
- }
- // Register default environment beans.
- if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
- beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
- }
- if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
- beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
- }
- if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
- beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
- }
- }
3.1 ApplicationContextDProcessor:Aware执行器
ApplicationContextDProcessor实现了BeanPostProcessor的postProcessBeforeInitialization接口,在所有Bean初始化前会执行当前方法
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- //判断Bean是Aware的子类
- if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
- bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
- bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
- return bean;
- }
- AccessControlContext acc = null;
- if (System.getSecurityManager() != null) {
- acc = this.applicationContext.getBeanFactory().getAccessControlContext();
- }
- if (acc != null) {
- AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
- invokeAwareInterfaces(bean);
- return null;
- }, acc);
- }
- else {
- //回调执行Aware接口
- invokeAwareInterfaces(bean);
- }
- return bean;
- }
如果当前Bean是Aware的子类,那么将Bean强转成Aware类型,通过回调将信息设置到Bean中
- private void invokeAwareInterfaces(Object bean) {
- if (bean instanceof EnvironmentAware) {
- ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
- }
- if (bean instanceof EmbeddedValueResolverAware) {
- ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
- }
- if (bean instanceof ResourceLoaderAware) {
- ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
- }
- if (bean instanceof ApplicationEventPublisherAware) {
- ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
- }
- if (bean instanceof MessageSourceAware) {
- ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
- }
- if (bean instanceof ApplicationContextAware) {
- ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
- }
- }
3.2 registerResolvableDependency:自动注入的支持
如果过容器中有多个相同接口的实现类,那么在自动注入的时候会注入注册的实现类
- beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
- beanFactory.registerResolvableDependency(ResourceLoader.class, this);
- beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
- beanFactory.registerResolvableDependency(ApplicationContext.class, this);
3.3 添加监听器执行器
ApplicationListenerDetector主要作用是添加和销毁监听器,实现了BeanPostProcessor的postProcessAfterInitialization(Bean实例化之后)方法和DestructionAwareBeanPostProcessor的postProcessBeforeDestruction(Bean销毁之前)方法
详情:https://www.jb51.net/article/277948.htm
四、BeanFactory的后置处理
这是个模压方法,由子类AnnotationConfigServletWebServerApplicationContext实现
- protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
- }
AnnotationConfigServletWebServerApplicationContext首先调了父类 ServletWebServerApplicationContext 的 postProcessBeanFactory 方法
- protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
- //4.1后置处理Bean工厂
- super.postProcessBeanFactory(beanFactory);
- if (this.basePackages != null && this.basePackages.length > 0) {
- //basePackages为空不会执行
- this.scanner.scan(this.basePackages);
- }
- if (!this.annotatedClasses.isEmpty()) {
- this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
- }
- }
4.1 后置处理bean工厂
父类ServletWebServerApplicationContext首先向Bean工厂中注入了一个执行器
- protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
- //4.1.1注入执行器
- beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
- beanFactory.ignoreDependencyInterface(ServletContextAware.class);
- //4.1.2注册作用域
- registerWebApplicationScopes();
- }
4.1.1 WebApplicationContextServletContextAwareProcessor
WebApplicationContextServletContextAwareProcessor继承了ServletContextAwareProcessor
ServletContextAwareProcessor继承了BeanPostProcessor实现了postProcessBeforeInitialization(Bean初始化前执行)
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- //注入ServletContext
- if (getServletContext() != null && bean instanceof ServletContextAware) {
- ((ServletContextAware) bean).setServletContext(getServletContext());
- }
- //注入ServletConfig
- if (getServletConfig() != null && bean instanceof ServletConfigAware) {
- ((ServletConfigAware) bean).setServletConfig(getServletConfig());
- }
- return bean;
- }
4.1.2 registerWebApplicationScopes 注册web的应用域
- // 所在类及方法:ServletWebServerApplicationContext#registerWebApplicationScopes
- private void registerWebApplicationScopes() {
- ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(getBeanFactory());
- WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
- existingScopes.restore();
- }
ExistingWebApplicationScopes是ServletWebServerApplicationContext类中的一个静态类
源码如下:
- public static class ExistingWebApplicationScopes {
- static {
- Set<String> scopes = new LinkedHashSet<>();
- scopes.add(WebApplicationContext.SCOPE_REQUEST);
- scopes.add(WebApplicationContext.SCOPE_SESSION);
- SCOPES = Collections.unmodifiableSet(scopes);
- }
- // 这是构造方法,大概就是根据SCOPES获取beanFactory中已经注册的scope,然后放入scopes
- // 需要注意的是,在上面的方法中,第二行才在向beanFactory中注册,也就是这时的beanFactory里面没有request和session这两个scop
- // 所以这里就完成了beanFactory的赋值。建议打断点进去看看
- public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- for (String scopeName : SCOPES) {
- Scope scope = beanFactory.getRegisteredScope(scopeName);
- if (scope != null) {
- this.scopes.put(scopeName, scope);
- }
- }
- }
- // 由于上面的方法并没有值存入scopes,所以这里也就没执行里面的内容
- public void restore() {
- this.scopes.forEach((key, value) -> {
- if (logger.isInfoEnabled()) {
- logger.info("Restoring user defined scope " + key);
- }
- this.beanFactory.registerScope(key, value);
- });
- }
- }
WebApplicationContextUtils.registerWebApplicationScopes(),这个方法就是向beanFactory注册web的scope了,源码如下
- public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
- registerWebApplicationScopes(beanFactory, null);
- }
- public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
- @Nullable ServletContext sc) {
- // 注册作用域
- beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());// 注册request SCOP
- beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());// 注册session SCOP
- if (sc != null) {
- ServletContextScope appScope = new ServletContextScope(sc);
- beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // 注册application SCOP
- // Register as ServletContext attribute, for ContextCleanupListener to detect it.
- sc.setAttribute(ServletContextScope.class.getName(), appScope);
- }
- // 添加依赖项
- beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
- beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
- beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
- beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
- if (jsfPresent) {
- FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
- }
- }
以上就是Spring refresh()源码解析的详细内容,更多关于Spring refresh()的资料请关注w3xue其它相关文章!