Spring refresh()源码解析

Kande ·
更新时间:2024-09-20
· 1135 次阅读

目录

正文

一、prepareRefresh:初始化前的预处理

1.1初始化属性值

1.2属性校验

二、obtainFreshBeanFactory:刷新Bean工厂

三、prepareBeanFactory:Bean工厂预处理

3.1 ApplicationContextDProcessor:Aware执行器

3.2 registerResolvableDependency:自动注入的支持

3.3 添加监听器执行器

四、BeanFactory的后置处理

4.1 后置处理bean工厂

4.1.1 WebApplicationContextServletContextAwareProcessor

4.1.2 registerWebApplicationScopes 注册web的应用域

正文 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()的资料请关注软件开发网其它相关文章!



spring 源码

需要 登录 后方可回复, 如果你还没有账号请 注册新账号