Spring ApplicationContext 简解
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
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) {
if (logger.isWarnEnabled()) {
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;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
prepareRefresh():准备需要刷新的资源。
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis(); //启动日期
this.closed.set(false); //激活标志
this.active.set(true); //激活标志 if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
} // Initialize any placeholder property sources in the context environment
initPropertySources(); //供扩展使用 // Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
class MyACTX extends ClassPathXmlApplicationContext {
@Override
protected void initPropertySources() {
super.initPropertySources();
//TODO
}
}
/**
* 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.
beanFactory.setBeanClassLoader(getClassLoader());
//表达式语言处理器,Spring3 SpEL表达式,#{xx.xx}支持。
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//属性编辑器支持 如处理Date注入
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks.
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.
//设置自动装配规则
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.
//AspectJ支持
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());
}
}
SpEL:Spring Expression Language,运行时构造复杂表达式,存取对象图属性,对象方法调用等。SpEL为单独模块,只依赖于core模块。
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${dataSource.driverClassName}"/>
<property name="url" value="${dataSource.url}"/>
<property name="username" value="${dataSource.username}"/>
<property name="password" value="${dataSource.password}"/>
<property name="maxActive" value="${dataSource.maxActive}"/>
<property name="minIdle" value="${dataSource.minIdle}" />
<property name="initialSize" value="${dataSource.initialSize}"></property>
<property name="validationQuery" value="${dataSource.validationQuery}"/>
</bean>
/**
* {@link BeanFactoryPostProcessor} implementation that allows for convenient
* registration of custom {@link PropertyEditor property editors}.
* 注册
*
*/
public class CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered { protected final Log logger = LogFactory.getLog(getClass()); private int order = Ordered.LOWEST_PRECEDENCE; // default: same as non-Ordered private PropertyEditorRegistrar[] propertyEditorRegistrars; private Map<Class<?>, Class<? extends PropertyEditor>> customEditors; ... ...
自定义Date属性编辑器MyDateEditor:
class MyDateEditor extends PropertyEditorSupport {
private String format = "yyyy-MM-dd";
public void setFormat(String format){
this.format = format;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
SimpleDateFormat sp = new SimpleDateFormat(format);
try{
this.setValue(sp.parse(text));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
配置:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="com.xxx.MyDateEditor">
<property name="format" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</entry>
</map>
</property>
</bean>
propertyEditorRegistrars:
自定义Date EditorRegister:
class MyDateRegister implements PropertyEditorRegistrar{
private String format = "yyyy-MM-dd";
public void setFormat(String format){
this.format = format;
}
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(format), true));
}
}
配置:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="com.xxx.MyDateRegister">
<property name="format" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</list>
</property>
</bean>
<!-- 国际化资源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<value>lang/message</value>
</property>
</bean>
读取:
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/lang-resource.xml");
String msg = ctx.getMessage("xxx", null, Locale.CHINA);
System.out.println(msg);
nitApplicationEventMulticaster():
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
} // Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
} // Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
... ...
Spring ApplicationContext 简解的更多相关文章
- Spring配置文件详解 – applicationContext.xml文件路径
Spring配置文件详解 – applicationContext.xml文件路径 Java编程 spring的配置文件applicationContext.xml的默 ...
- spring配置文件详解--真的蛮详细
spring配置文件详解--真的蛮详细 转自: http://book.51cto.com/art/201004/193743.htm 此处详细的为我们讲解了spring2.5的实现原理,感觉非常 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- J2EE进阶(四)Spring配置文件详解
J2EE进阶(四)Spring配置文件详解 前言 Spring配置文件是用于指导Spring工厂进行Bean生产.依赖关系注入(装配)及Bean实例分发的"图纸".Java EE程 ...
- Spring学习(一)-----Spring 模块详解
官方下载链接:http://repo.spring.io/release/org/springframework/spring/ Spring 模块详解: Core 模块 spring-beans-3 ...
- Spring AOP详解及简单应用
Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- 转:Spring AOP详解
转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- [转载]Spring配置文件详解一:
原文地址:与base-package="com.xx">Spring配置文件详解一:<context:annotation-config/>与<contex ...
- JAVA总结--Spring框架全解
一.Spring简介 Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring 框架目标是简化Java企业 ...
随机推荐
- 最好的5个Android ORM框架
在开发Android应用时,保存数据有这么几个方式, 一个是本地保存,一个是放在后台(提供API接口),还有一个是放在开放云服务上(如 SyncAdapter 会是一个不错的选择). 对于第一种方式, ...
- LBaaS 实现机制 - 每天5分钟玩转 OpenStack(125)
上一节我们已经配置并测试 LBaaS,今天重点分析 Neutron 是如何用 Haproxy 来实现负责均衡的. 在控制节点上运行 ip netns,我们发现 Neutron 创建了新的 namesp ...
- Django:手把手带你入门
一.开发环境: Python:2.7:PyCharm 4 二.Django的安装: 打开Pycharm --> 新建项目--> 看图操作--> 自动安装Django环境 三.创建第一 ...
- OpenNLP:驾驭文本,分词那些事
OpenNLP:驾驭文本,分词那些事 作者 白宁超 2016年3月27日19:55:03 摘要:字符串.字符数组以及其他文本表示的处理库构成大部分文本处理程序的基础.大部分语言都包括基本的处理库,这也 ...
- Oracle基础维护02-表、主键、索引、表结构维护手册
目录 一.项目新建表.主键.索引注意事项 二.举例说明建表.主建.索引的操作方法 2.1 设定需求如下 2.1.1 查询数据库有哪些表空间 2.1.2 本文档假设数据库有这两个业务用户的表空间 2.2 ...
- 安卓v7支持包下的ListView替代品————RecyclerView
RecyclerView这个控件也出来很久了,相信大家也学习的差不多了,如果还没学习的,或许我可以带领大家体验一把这个艺术般的控件. 项目已经同步至github:https://github.com/ ...
- 通过Http接口及SolrNet 两种方法基于Solr5.5.1 实现CURD
前言 老规矩,任何技术的入门我通常都会总结增删改查,本文我就通过HttpWebRequest和SolrNet的方式实现Solr最基础的增删改查(CURD).对于自己的完整项目,同时不想过于依赖第三方类 ...
- c#编程基础之字符串函数
c#常用的字符串函数 例一: 获取字符串的大小写函数 ToLower():得到字符串的小写形式 ToUpper():得到字符串的大写形式 注意: 字符串时不可变的,所以这些函数都不会直接改变字符串的内 ...
- linux内核数据结构之kfifo
1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...
- ASP.NET Core 中文文档 第二章 指南(4.4)添加 Model
原文:Adding a model 作者:Rick Anderson 翻译:娄宇(Lyrics) 校对:许登洋(Seay).孟帅洋(书缘).姚阿勇(Mr.Yao).夏申斌 在这一节里,你将添加一些类来 ...