主题

接上文Spring 学习记录7 初识XmlWebApplicationContext

refresh方法

refresh方法是定义在父类AbstractApplicationContext中的.它内部会调用很多方法.有一些是在子类中实现的.算是模板方法的设计模式吧.主要作用就是初始化wac加载各种bean等作用.

 @Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 记录开始wac开始初始化的时间,设置激活标记,servlet的相关param设置到env(之前做过1次),校验env中必须的props
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
// 刷新初始化BF并获取它,将旧的BF里的bean删掉,新建1个BF,加载XML配置文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
initMessageSource(); // Initialize event multicaster for this context.
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
onRefresh(); // Check for listener beans and register them.
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex); // Destroy already created singletons to avoid dangling resources.
destroyBeans(); // Reset 'active' flag.
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
}
}
}

prepareRefresh方法

第一个被调用的方法就是它

主要作用:

记录开始wac开始初始化的时间,设置激活标记,servlet的相关param设置到env(之前做过1次),校验env中必须的props

     /**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
* 记录开始wac开始初始化的时间,设置激活标记,servlet的相关param设置到env(之前做过1次),校验env中必须的props
*/
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.active.set(true); if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
} // Initialize any placeholder property sources in the context environment
// 讲servlet的config和context里的params赋值给env..之前已经做过一次了,这个wac可能会由servlet初始化,这样的话ServletConfig就不会为空
initPropertySources(); // Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
// 在env中有一些properties是必须的,校验这些props.没有就抛出异常
getEnvironment().validateRequiredProperties();
}

L16..这个方法做了什么直接看注释吧..

     /**
* {@inheritDoc}
* <p>Replace {@code Servlet}-related property sources.
*/
@Override
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, this.servletConfig);
}
}

就是拿servletContext和servletConfig去填充env....和之前做的一样....如果是listener初始化的话这里servletConfig肯定是空的.

L21 对env里的必须的属性进行校验.如果这些属性不存在的话就报错.(但是我源码里搜索了一下并没有找到调用设置必须属性的地方...不知道怎么使用才能标记属性为必须....)

obtainFreshBeanFactory方法

主要作用:

刷新初始化BF并获取它,将旧的BF里的bean删掉,新建1个BF,加载XML配置文件

     /**
* Tell the subclass to refresh the internal bean factory.
* 刷新初始化BF并获取它,将旧的BF里的bean删掉,新建1个BF,加载XML配置文件
*
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory(); // 刷新BF
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

L10 refreshBeanFactory();

     /**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans(); // 删除所有单例bean
closeBeanFactory(); // wac中的BF成员域=null.
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory(); // 创建1个新的DefaultListableBeanFactory
beanFactory.setSerializationId(getId()); // 设置ID
customizeBeanFactory(beanFactory); // wac 中的属性 allowBeanDefinitionOverriding allowCircularReferences 覆盖BF
loadBeanDefinitions(beanFactory); // 加载BeanDefinitions.
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

主要作用就是先把之前的beanfactory里创建的bean都销毁,然后销毁beanfactory.

然后新建1个DefaultListableBeanFactory,并配置一些通过wac配置的属性.

再加载一下bean的配置.在这里因为wac是XmlWebApplicationContext,所以bean的配置肯定是写在XML里的了.

最后把bf对象设置到wac的成员域上.

L11得到之前设置的新的BF并在L15返回...

prepareBeanFactory方法

主要作用:

1.设置BF解析bean配置需要用到的一些对象比如env. 2.注册一些BeanPostProcessor比如ApplicationContextAwareProcessor去设置Aware需要的对象 3.忽略一些特定class注入的对象,设置一些特定class注入的对象为指定值 4.将一些env中的properties map当做bean注册到BF中

 /**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
*
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// BF需要解析属性或者转化需要用到env和其他相关的类.从wac中设置进去
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks.
// 因为bean是在BF中创建的,所以如果他们需要用到wac的callback比如ApplicationEventPublisherAware的方法或者ApplicationContextAware,
// 那就需要再BF生成bean的时候注入applicationcontext或者它的相关类.比如env
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class); // BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 如果要注入以下类型的bean,直接使用这些对象
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, 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.
// 将一些properties当做bean放到BF中
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());
}
}

第一个代码块就是设置一些BF解析bean需要用到的对象.比如env.

第二个代码块就是add了一些XXXAwareProcess.比如applicationContextAware...BF在创建这个bean以后会调用ApplicationContextAwareProcessor的回调函数去注入applicationContext.

然后忽略了一些接口,他们不会被注入实现类.

第三个代码块配置了一些接口的注入的实现类.

第四个代码又注入了一个BeanPostProcessor,这个似乎和AOP有关系.没研究过.

第五个代码块就是把env中的一些props当做bean注册到BF中去.

postProcessBeanFactory方法

又是1个模板方法.可以对BF进行一些加工定制.

在web环境下有重写过.

主要作用:

1.设置一个BeanPostProcess为ServletContextAware的实现类注入servlet相关对象
2.在BF中增加requetsScope等Scope
3.把servletContext,Config,ServletInitParams,ServletAttribute当做Bean注册到BF中
     /**
* Register request/session scopes, a {@link ServletContextAwareProcessor}, etc.
* 1.设置一个BeanPostProcess为ServletContextAware的实现类注入servlet相关对象
* 2.在BF中增加requetsScope等Scope
* 3.把servletContext,Config,ServletInitParams,ServletAttribute当做Bean注册到BF中
*
*/
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置一个BeanPostProcess为ServletContextAware的实现类注入servlet相关对象
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class); // 在BF中增加requetsScope等Scope
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
// 把servletContext,Config,ServletInitParams,ServletAttribute当做Bean注册到BF中
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

invokeBeanFactoryPostProcessors方法

初始化并调用配置的BeanFactoryPostProcessor..具体比较复杂.等后续更多学习以后再分享.

registerBeanPostProcessors方法

基本同invokeBeanFactoryPostProcessors方法,这是这里不会调用BeanPostProcess只是向BF里注册而已.具体比较复杂.等后续更多学习以后再分享.

Spring 学习记录8 初识XmlWebApplicationContext(2)的更多相关文章

  1. Spring 学习记录7 初识XmlWebApplicationContext

    主题 之前Spring相关的一些类,比如Enviromnent,BenFactory都接触了一些.有一些收获.但是直接看代码很多方法都不知为什么这样写.哪里会用到.因为太底层了.不好理解..现在从高层 ...

  2. 我的Spring学习记录(二)

    本篇就简单的说一下Bean的装配和AOP 本篇的项目是在上一篇我的Spring学习记录(一) 中项目的基础上进行开发的 1. 使用setter方法和构造方法装配Bean 1.1 前期准备 使用sett ...

  3. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

  4. 我的Spring学习记录(五)

    在我的Spring学习记录(四)中使用了注解的方式对前面三篇做了总结.而这次,使用了用户登录及注册来对于本人前面四篇做一个应用案例,希望通过这个来对于我们的Spring的使用有一定的了解. 1. 程序 ...

  5. Spring 学习记录3 ConversionService

    ConversionService与Environment的关系 通过之前的学习(Spring 学习记录2 Environment),我已经Environment主要是负责解析properties和p ...

  6. Spring 学习记录6 BeanFactory(2)

    主题 除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类. 结构 DefaultListabl ...

  7. Spring学习记录(九)---通过工厂方法配置bean

    1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. package com.guigu.spring.factory; public class C ...

  8. Spring学习记录(七)---表达式语言-SpEL

    SpEL---Spring Expression Language:是一个支持运行时查询和操作对象图表达式语言.使用#{...}作为定界符,为bean属性动态赋值提供了便利. ①对于普通的赋值,用Sp ...

  9. 【Android】学习记录<1> -- 初识ffmpeg

    工作需要用到ffmpeg来进行Android的软编码,对这玩意儿一点都不了解,做个学习记录先. FFmpeg:http://www.ffmpeg.org Fmpeg is the leading mu ...

随机推荐

  1. python笔记-7(shutil/json/pickle/shelve/xml/configparser/hashlib模块)

    一.shutil模块--高级的文件.文件夹.压缩包处理模块 1.通过句柄复制内容 shutil.copyfileobj(f1,f2)对文件的复制(通过句柄fdst/fsrc复制文件内容) 源码: Le ...

  2. pymongo和mongodbengine之间的区别

    pymongo是一个mongo driver,可以用来连接数据库以及对数据库进行操作,但是是用mongo自己的用来操作数据库的语句进行操作数据库,而mongodbengine就像是sqlalchemy ...

  3. Vim使用YouCompleteMe达到类似IDE的代码提示、补全,以及其他实用设置

    接触Linux有两年了,vim还是只会简单的操作.最近实在受不了sublime的代码提示,决定花点时间来配置下vim.本文讲自己认为方便的vim配置,称不上完美,只讲究简单实用. 使用 ctags 主 ...

  4. oracle 内存分配和调优 总结

    一直都想总结一下oracle内存调整方面的知识,最近正好优化一个数据库内存参数,查找一些资料并且google很多下.现在记录下来,做下备份.           一.概述:              ...

  5. 使用Navicat for Oracle新建表空间、用户及权限赋予 (转)

    Navicat for Oracle是有关Oracle数据库的客户端工具.通过这个客户端,我们可以图形方式对Oracle数据库进行操作. 说明我们此次试验的Oracle数据库版本是Oracle 10G ...

  6. 使用FileZilla连接Linux

      FileZilla是一个免费开源的FTP软件,分为客户端版本和服务器版本,具备所有的FTP软件功能.可控性.有条理的界面和管理多站点的简化方式使得Filezilla客户端版成为一个方便高效的FTP ...

  7. 用活firewalld防火墙之service

    原文地址:http://www.excelib.com/article/291/show 前面学生已经给大家介绍了在firewalld中service的概念以及在zone中怎么使用service,但是 ...

  8. 【CSS】文字超出显示省略号&连续字符换行

    方法1.多行控制(css3) .text { width: 100%; word-break: break-all; display: -webkit-box; -webkit-line-clamp: ...

  9. Java-Runoob-高级教程:Java 序列化

    ylbtech-Java-Runoob-高级教程:Java 序列化 1.返回顶部 1. Java 序列化 Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包 ...

  10. 杂项-数学软件:Mathematica

    ylbtech-杂项-数学软件:Mathematica Mathematica是一款科学计算软件,很好地结合了数值和符号计算引擎.图形系统.编程语言.文本系统.和与其他应用程序的高级连接.很多功能在相 ...