- 浏览: 447198 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (162)
- easymock (3)
- 模板引擎 (3)
- JForum (4)
- web (9)
- spring (10)
- java (20)
- struts (9)
- uml (3)
- java pattern (19)
- JQuery (14)
- 多线程 (13)
- database (21)
- PS (3)
- ejb (6)
- 版本管理 svn , maven , ant (2)
- protocol (1)
- 测试 (1)
- ws (7)
- Apache (4)
- 脚本语言 (1)
- guice (1)
- 分布式 (4)
- 架构 (0)
- 经验 (1)
- 版本管理 svn (1)
- maven (1)
- ant (1)
- 书籍 (1)
- Linux (1)
最新评论
-
Master-Gao:
稍微明白了点,,有点萌萌哒
为什么匿名内部类参数必须为final类型 -
waw0931:
终于明白了,谢谢!
为什么匿名内部类参数必须为final类型 -
十三圆桌骑士:
提供了两个链接还是有用的。
安装Mondrian -
放方芳:
[flash=200,200][/flash]
Freemarker标签使用 -
放方芳:
[b][/b]
Freemarker标签使用
1
2
3
|
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring-config.xml" );
FooService foo = (FooService) ctx.getBean( "FooService" );
|
我们看第一行初始化了一个ClassPathXmlApplicationContext对象,
注:也可以用FileSystemXmlApplicationContext来加载,两者的区别只是查找配置文件的起始路径不同,一个以classpath为当前路径,一个是直接用文件系统的当前路径,内部没有太大区别。
注2:web工程大家都知道我们配置了ContextLoaderListener,这里暂时不做介绍,后面会有专门的分析,起始主题流程都差不多,详情请参见:从源码看Spring在web工程中的初始化。
请看下面的构造方法,参数是spring配置文件在classpath中的全路径名:
1
2
3
|
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this ( new String[] {configLocation}, true , null );
} |
可以看到里面调用了另外一个构造方法(如下),其中传递了两个默认参数refresh=true立即刷新,parent=null继承为空,并且把配置文件封装为了一个String数组,这里主要是因为spring是支持多个配置文件的
1
2
3
4
5
6
7
8
9
|
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super (parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
} |
我们看这个构造方法的代码:
- 首先调用了父类的构造函数
- 调用setConfigLocations设置配置文件位置信息(代码如下)
- 判断如果refresh为true则调用refresh()方法,refresh方法在AbstractApplicationContext中
setConfigLocations代码:
很简单,主要是检验是否传入参数为空然后赋值给configLocations属性,不过其中有两个小特点可以注意一下:
- 并没有直接把传入参数locations直接赋值给属性,而是new了一个String数组,然后循环赋值,这里主要是出于安全考虑避免外面传入的字符串数组变化影响spring内部
- 可以看到赋值前有调用了一下resolvePath方法,这个方法实现了一些系统变量的替换,例如路径里可以使用${}加载系统变量值
1
2
3
4
5
6
7
8
9
10
11
12
|
public void setConfigLocations(String[] locations) {
if (locations != null ) {
Assert.noNullElements(locations,
"Config locations must not be null" );
this .configLocations = new String[locations.length];
for ( int i = 0 ; i < locations.length; i++) {
this .configLocations[i] = resolvePath(locations[i]).trim();
}
} else {
this .configLocations = null ;
}
} |
下面看refresh刷新方法,这个刷新方法主要是从配置文件加载bean配置的过程,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public void refresh() throws BeansException, IllegalStateException {
// 整个刷新过程是同步的
synchronized ( this .startupShutdownMonitor) {
// 刷新前的准备工作
prepareRefresh();
// 关闭释放旧的beanFactory创建新的beanFactory,读取配置文件等
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 对beanFactory进行一些基本的初始化
prepareBeanFactory(beanFactory);
try {
// 下面两行主要用户扩展,处理所有已注册的BeanFactoryPostProcessor,实现在已经加载配置但未初始化bean时对配置进行修改
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
// 处理所有已注册的BeanPostProcessor,主要用于扩展,实现bean初始化前后的一些定制操作
registerBeanPostProcessors(beanFactory);
// 初始化消息源bean
initMessageSource();
// 初始化事件监听器集,也有人叫事件监听器的注册表,所有的事件监听器都在这个bean里进行管理
initApplicationEventMulticaster();
// 主要用于扩展,实现一些特殊bean的初始化,时间点是类似消息源事件监听器集等特殊bean初始化后,普通的bean初始化前
onRefresh();
// 注册监听器
registerListeners();
// 初始化其余的非延迟加载的单例bean
finishBeanFactoryInitialization(beanFactory);
// 刷新完成调用LifecycleProcessor的onRefresh方法,并且发布ContextRefreshedEvent事件
finishRefresh();
} catch (BeansException ex) {
// 销毁已经创建的单例bean
destroyBeans();
// 重新设置active标记
cancelRefresh(ex);
throw ex;
}
}
} |
上面是一个spring初始化的基本流程框架,后面几篇将陆续对其中每一个方法进行详细的分析
上篇结束的地方简单介绍了一下refresh()方法,现在我们具体分析一下它的代码细节:
1.首先可以看到整个refresh()的代码都是同步的,对应的同步对象是startupShutdownMonitor,我们看一下startupShutdownMonitor引用的地方,可以知道,只有在refresh()和close()两个方法里用到,说明这个锁是用来同步applicationContext的刷新和销毁的。
2.同步代码块的第一行是prepareRefresh()方法,代码如下:
1
2
3
4
5
6
7
8
9
|
protected void prepareRefresh() {
this .startupDate = System.currentTimeMillis();
synchronized ( this .activeMonitor) {
this .active = true ;
}
if (logger.isInfoEnabled()) {
logger.info( "Refreshing " + this );
}
} |
这个方法也很简单
- 首先设置startupDate为系统当前毫秒数,代表当前applicationContext的创建时间;
- 设置active为true,代表当前applicationContext是活动的,可以看到对active的赋值操作是同步的,同步对象为activeMonitor,查看active的引用点,可以看到所有对 active的操作都是同步在activeMonitor下的,在调用cancelRefresh()和doClose()两个方法的时候会把它设置为false,其中cancelRefresh()代表中止refresh,doClose()则是当前applicationContext的关闭销毁方法
- 最后是日志的打印,info级别,我这里要说的一点是后面直接+this,代表会调用toString方法,AbstractApplicationContext重写了toString,大概格式是displayName+startup+parent displayName
3.接着是这一行:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(),obtainFreshBeanFactory代码如下:
1
2
3
4
5
6
7
8
|
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug( "Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
} |
第一行调用refreshBeanFactory(),我们先跳过这行看下面,调用了getBeanFactory()获得beanFactory对象然后返回这个对象,看getBeanFactory()的代码可以看到,是做了一个同步,然后取出当前对象里的beanFactory,同步锁是beanFactoryMonitor:
注:refreshBeanFactory()和getBeanFactory()方法在AbstractRefreshableApplicationContext类里面,关于ApplicationContext的类结构我会在另外一篇文章里做专门介绍,请看:ApplicationContext的类继承结构及框架图
1
2
3
4
5
6
7
8
9
|
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized ( this .beanFactoryMonitor) {
if ( this .beanFactory == null ) {
throw new IllegalStateException( "BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext" );
}
return this .beanFactory;
}
} |
如果beanFactory为空则会抛出异常,其实一开始beanFactory肯定是null的,beanFactory的创建就是在refreshBeanFactory()方法中,下面我们看它的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized ( this .beanFactoryMonitor) {
this .beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException( "I/O error parsing bean definition source for " + getDisplayName(), ex);
}
} |
前面3行代码首先判断是否hasBeanFactory(),如果存在则调用destroyBeans()以及closeBeanFactory():
- hasBeanFactory()是在判断属性beanFactory是否为空,当然同上面一样beanFactory的操作是同步的,同步对象是beanFactoryMonitor。
- destroyBeans()方法只有一行代码:getBeanFactory().destroySingletons(),调用了beanFactory对象的destroySingletons()方法来销毁所有单例bean。(后面还会用到这个方法,放到后面详细介绍)
- closeBeanFactory()和上面一样,依旧是同步的情况下处理beanFactory属性,首先调用setSerializationId(null),然后把beanFactory属性设置为null。
接下来后面的代码是一个创建beanFactory的过程:
-
调用createBeanFactory()方法创建一个beanFactory对象:
查看方法代码可以看到创建的是一个DefaultListableBeanFactory对象,参数parent传递的方法getInternalParentBeanFactory()返回的结果,getInternalParentBeanFactory()方法的代码为:
(getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent()
如果当前applicationContext对象的parent是ConfigurableApplicationContext类的实例则返回当前对象的parent的beanFactory对象,否则直接返回当前对象的parent。
-
将当前对象的id属性作为参数调用为beanFactory对象的setSerializationId()方法,我们这里看下这个方法的代码:
123456789
public
void
setSerializationId(String serializationId) {
if
(serializationId !=
null
) {
serializableFactories.put(serializationId,
new
WeakReference<DefaultListableBeanFactory>(
this
));
}
else
if
(
this
.serializationId !=
null
) {
serializableFactories.remove(
this
.serializationId);
}
this
.serializationId = serializationId;
}
(1)在serializableFactories里加入一组值:键为serializationId,值为当前对象的弱引用
(2)从serializableFactories中移除键为当前对象属性serializationId的对象,也就是以前存入的当前对象的弱引用
(3)设置属性serializationId为输入参数
-
customizeBeanFactory()方法的代码:
12345678910
protected
void
customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if
(
this
.allowBeanDefinitionOverriding !=
null
) {
beanFactory.setAllowBeanDefinitionOverriding(
this
.allowBeanDefinitionOverriding);
}
if
(
this
.allowCircularReferences !=
null
) {
beanFactory.setAllowCircularReferences(
this
.allowCircularReferences);
}
beanFactory.setParameterNameDiscoverer(
new
LocalVariableTableParameterNameDiscoverer());
beanFactory.setAutowireCandidateResolver(
new
QualifierAnnotationAutowireCandidateResolver());
}
如果属性allowCircularReferences不为空,设置给beanFactory对象相应属性,此属性的含义:是否允许bean之间循环引用
设置beanFactory的parameterNameDiscoverer属性为一个新的LocalVariableTableParameterNameDiscoverer对象,主要用asm解析class文件
设置beanFactory的parameterNameDiscoverer属性为一个新的QualifierAnnotationAutowireCandidateResolver对象,主要用于自动装配的处理
-
loadBeanDefinitions()方法的代码:
1234567
protected
void
loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws
BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader =
new
XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setResourceLoader(
this
);
beanDefinitionReader.setEntityResolver(
new
ResourceEntityResolver(
this
));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
第2行设置beanDefinitionReader的resourceLoader属性为当前对象
第3行设置beanDefinitionReader的entityResolver属性为一个新的ResourceEntityResolver对象,输入参数resourceLoader为当前对象,这个数要是用来解析xml的
第4行设置beanDefinitionReader的validationMode以及namespaceAware,参数是当前对象的validating属性,主要用于xml校检
最后一行是做了xml配置文件的读取,就不做详细描述了,有个细节是会循环加载configResources、configLocations两个里面的文件
- 接着是同步操作beanFactory,把创建的beanFactory对象赋值给当前ApplicationContext的beanFactory属性
refresh()方法中在上篇obtainFreshBeanFactory()方法创建了beanfactory对象,之后的代码就开始是对beanFactory对象的一些处理,BeanFactory相关的一些内容也是spring的核心内容。
注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。
一、首先是prepareBeanFactory(beanFactory),主要是做了一些beanFactory的初始化工作,因为这个方法比较长,我们分成4部分来看,
第1部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver( new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar( new ResourceEditorRegistrar( this ));
beanFactory.addBeanPostProcessor( new ApplicationContextAwareProcessor( this ));
beanFactory.ignoreDependencyInterface(ResourceLoaderAware. class );
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware. class );
beanFactory.ignoreDependencyInterface(MessageSourceAware. class );
beanFactory.ignoreDependencyInterface(ApplicationContextAware. class );
beanFactory.registerResolvableDependency(BeanFactory. class , beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader. class , this );
beanFactory.registerResolvableDependency(ApplicationEventPublisher. class , this );
beanFactory.registerResolvableDependency(ApplicationContext. class , this );
|
- 第1行设置beanFactory的classLoader为当前context的classLoader
- 第2行设置beanFactory的表达式语言处理器,spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值。
- 第3行为beanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具,以后再做详细分析。
- 第4行添加了一个处理aware相关接口的beanPostProcessor扩展,主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法实现aware相关接口的功能,aware接口是用来给bean注入一些资源的接口,例如实现BeanFactoryAware的Bean在初始化后,Spring容器将会注入BeanFactory的实例相应的还有ApplicationContextAware、ResourceLoaderAware、ServletContextAware等等。
- 第5-8行设置了几个忽略自动装配的接口,默认只有BeanFactoryAware被忽略,其他的都要自行设置,这里设置了ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware和ApplicationContextAware。
- 第9-12行设置了几个自动装配的特殊规则,如果是BeanFactory类型,则注入beanFactory对象,如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext类型则注入当前对象(applicationContext对象)。
第2部分代码:
1
2
3
4
|
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor( new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader( new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
} |
- 这部分判断是否定义了名为loadTimeWeaver的bean,如果定义了则添加loadTimeWeaver功能的beanPostProcessor扩展,并且创建一个临时的classLoader来让其处理真正的bean。spring的loadTimeWeaver主要是通过 instrumentation 的动态字节码增强在装载期注入依赖。具体这部分还没有很好的理解,暂时标记一下以后再专门研究看看。
第3部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
Map systemProperties;
try {
systemProperties = System.getProperties();
} catch (AccessControlException ex) {
systemProperties = new ReadOnlySystemAttributesMap() {
protected String getSystemAttribute(String propertyName) {
try {
return System.getProperty(propertyName);
} catch (AccessControlException ex) {
if (logger.isInfoEnabled()) {
logger.info( "Not allowed to obtain system property [" + propertyName + "]: " +
ex.getMessage());
}
return null ;
}
}
};
}
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, systemProperties);
} |
- 这部分首先判断是否定义了名为systemProperties的bean,如果没有则加载系统获取当前系统属性System.getProperties()并注册为一个单例bean。假如有AccessControlException权限异常则创建一个ReadOnlySystemAttributesMap对象,可以看到创建时重写了getSystemAttribute()方法,查看ReadOnlySystemAttributesMap的代码可以得知在调用get方法的时候会去调用这个方法来获取key对应的对象,当获取依旧有权限异常AccessControlException的时候则返回null。
第4部分代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
Map<String,String> systemEnvironment;
try {
systemEnvironment = System.getenv();
} catch (AccessControlException ex) {
systemEnvironment = new ReadOnlySystemAttributesMap() {
protected String getSystemAttribute(String variableName) {
try {
return System.getenv(variableName);
} catch (AccessControlException ex) {
if (logger.isInfoEnabled()) {
logger.info( "Not allowed to obtain system environment variable [" + variableName + "]: " +
ex.getMessage());
}
return null ;
}
}
};
}
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, systemEnvironment);
} |
- 这部分和上面一部分类似,只不过由系统属性改为了系统环境变量,异常处理方式等也和上面一部分一样。这两部分都是为spring内部提供系统信息的支撑bean。
二、prepareBeanFactory()方法调用之后,是一个try-catch代码块,如果有BeanException异常产生则会停止refresh并且销毁已创建的资源,现在看代码块里的第一行postProcessBeanFactory(beanFactory)
postProcessBeanFactory()方法,默认方法体是空的,主要是用来扩展beanfactory的,扩展点是在bean等配置都已经加载但还没有进行实例化的时候。
例如上面说到的aware相关接口自动装配设置,假如是web项目,使用的是spring的webApplicationcontext,这时需要一些ServletContextAware相关的自动装配忽略及配置等,就需要在webApplicationContext里重写这个方法来实现相应功能。
refresh()方法中在上篇看到了postProcessBeanFactory(beanFactory),这篇继续往下看。
注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。
一、invokeBeanFactoryPostProcessors(beanFactory),这个方法从名字就可以看出是在调用BeanFactoryProcessor,代码也比较长,分成几部分来看。
第1部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor. class , true , false );
List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
OrderComparator.sort(registryPostProcessorBeans);
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
processedBeans.addAll(beanMap.keySet());
} else {
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
} |
- 首先创建一个HashSet变量processedBeans,接着是个判断,如果beanFactory类型实现了BeanDefinitionRegistry接口,强转beanFactory对象为BeanDefinitionRegistry类型变量registry,创建两个LinkedList变量regularPostProcessors用来存储普通PostProcessor;registryPostProcessors用来存储一些用来对bean定义的注册信息进行处理的PostProcessor。
- 7-17行循环所有applicationContext中已经注册的BeanFactoryPostProcessor,如果是实现了BeanDefinitionRegistryPostProcessor的类型,则调用对应的postProcessBeanDefinitionRegistry()方法进行相应处理并加入到registryPostProcessors中,否则加入到regularPostProcessors中。
- 18-25行首先调用BeanFactory的getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)方法获取所有类型为BeanDefinitionRegistryPostProcessor的bean,然后放到List对象registryPostProcessorBeans中并且进行排序,排序之后循环调用每个bean的postProcessBeanDefinitionRegistry()方法。
注:getBeansOfType()后续会有一个针对beanFactory的专门研究先不做详细分析,这里简单说一下排序,spring内部实现了一套排序方法,主要是一个Ordered接口,需要排序的对象实现这个接口的getOrder()方法,在进行排序的时候会对这个结果进行比较从而实现排序。另外假如某个对象实现的是PriorityOrdered接口则优先进行排序,同样情况则依旧比较getOrder()的结果。 - 26-28行依次对3个List对象调用invokeBeanFactoryPostProcessors()方法,进行BeanFactoryPostProcessor的处理,顺序为registryPostProcessors、registryPostProcessorBeans、regularPostProcessors。invokeBeanFactoryPostProcessors()方法的代码很简单,就是for循环调用每个postProcessor对象的postProcessBeanFactory(beanFactory)方法。
- 29行把所有bean中加载过来的BeanDefinitionRegistryPostProcessor类型的bean的名字加入到processedBeans中。
- 回到上面最开始的判断,如果beanFactory类型没有实现BeanDefinitionRegistry接口,则直接调用invokeBeanFactoryPostProcessors()方法处理所有ApplicationContext已注册的BeanFactoryPostProcessor。
第2部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor. class , true , false );
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (isTypeMatch(ppName, PriorityOrdered. class )) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor. class ));
}
else if (isTypeMatch(ppName, Ordered. class )) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
} OrderComparator.sort(priorityOrderedPostProcessors); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor. class ));
} OrderComparator.sort(orderedPostProcessors); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor. class ));
} invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); |
- 第1、2行首先获取所有类型为BeanFactoryPostProcessor的bean的name集合放到变量postProcessorNames
- 第3行建立一个ArrayList变量priorityOrderedPostProcessors用来存储需优先处理的postProcessor
- 第4、5行分别建立两个ArrayList变量orderedPostProcessorNames、nonOrderedPostProcessorNames用来存储有排序的和无排序的postProcessor
- 第6-19行循环上面获取到的所有postProcessor的name集合,按条件进行不同处理:
如果name已经存在于processedBeans则代表是已经处理过了,跳过这一个;
调用isTypeMatch()方法根据bean的name判断该bean是否实现了PriorityOrdered接口(上面我们说过排序中这个属于优先排序),如果是的话根据该name取出对应的bean对象加入到priorityOrderedPostProcessors集合中;
调用isTypeMatch()方法根据bean的name判断该bean是否实现了Ordered接口(上面我们说过实现了这个接口就可以进行排序了),如果是的话把该name加入到orderedPostProcessorNames集合中;
如果都上面条件都不成立,则加入到nonOrderedPostProcessorNames集合中;
注:关于isTypeMatch()方法,说起来简单就是根据bean的name取出bean对象然后进行类型判断,但实际上这个方法并不简单,最终主逻辑代码在AbstractBeanFactory中,做个标记,以后单独抽出来分析一下。 - 第20行对priorityOrderedPostProcessors进行排序
- 第21行调用invokeBeanFactoryPostProcessors()方法对priorityOrderedPostProcessors中的所有postProcessor进行处理
- 第23-28行通过getBean()方法取得所有orderedPostProcessorNames集合中postProcessor的bean对象,然后加入到一个新的集合变量orderedPostProcessors中,然后对这个集合排序,最后调用invokeBeanFactoryPostProcessors()方法处理
- 后面的一部分是对无排序的nonOrderedPostProcessorNames进行处理,除了去掉排序步骤之外和上面的步骤一样,就不重复描述了
二、我们回到refresh()方法中,看下一行:registerBeanPostProcessors(beanFactory),这个方法主要就是对BeanPostProcessor的注册,依旧分为几部分来看:
第1部分:
1
2
3
|
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor. class , true , false );
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor( new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
|
- 第1行获取所有的BeanPostProcessor类型的bean的name数组
- 第2行计算BeanPostProcessor的数量:banFactory中已注册的BeanPostProcessor的数量 + 1 + 上面获取到的所有bean中的BeanPostProcessor的数量。这里面的那个+1,是下一行的BeanPostProcessorChecker
- 第3行注册一个BeanPostProcessorChecker到beanFactory中,这个BeanPostProcessor作用是当一个bean创建后没有被所有的BeanPostProcessor处理的时候打印一行info级别日志
第2部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (isTypeMatch(ppName, PriorityOrdered. class )) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor. class );
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (isTypeMatch(ppName, Ordered. class )) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
} |
- 这部分代码与BeanFactoryPostProcessor的处理那部分类似,就是把所有的BeanPostProcessor进行区分放到不同集合里,优先的、排序的、无排序的。有个特殊的地方就是多了一个internalPostProcessors集合,用来存放优先级别中类型为MergedBeanDefinitionPostProcessor的BeanPostProcessor。它的主要作用是在spring运行时合并处理bean定义,例如注解中的bean定义,这部分也还没完全弄清楚,做个标记,回头专项分析。
第3部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
OrderComparator.sort(priorityOrderedPostProcessors); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor. class );
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} OrderComparator.sort(orderedPostProcessors); registerBeanPostProcessors(beanFactory, orderedPostProcessors); List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor. class );
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); OrderComparator.sort(internalPostProcessors); registerBeanPostProcessors(beanFactory, internalPostProcessors); beanFactory.addBeanPostProcessor( new ApplicationListenerDetector());
|
- 第1-2行对priorityOrderedPostProcessors进行排序,并调用registerBeanPostProcessors()方法进行注册处理,这个方法内部代码比较简单,就是循环这个集合并调用beanFactory.addBeanPostProcessor(postProcessor)把每个BeanPostProcessor注册到beanFactory。
- 第3-13行和之前也类似了,把所有orderedPostProcessorNames中的BeanPostProcessor取出来放到集合里,其中MergedBeanDefinitionPostProcessor类型的依旧加入到internalPostProcessors中。最后两行先排序,再调用registerBeanPostProcessors()方法进行注册处理
- 第14-23行是对nonOrderedPostProcessorNames的处理,相比上面去掉了排序过程,其他依旧。
- 紧接着的是对internalPostProcessors排序,注册处理。
- 最后一行注册了一个BeanPostProcessor:ApplicationListenerDetector,这个是AbstractApplicationContext的内部类,实现了MergedBeanDefinitionPostProcessor接口,这个类只是暂时知道是在处理ApplicationListener相关的东西,具体作用还未知,留待分析。
refresh()方法中在上篇看完了对PostProcessors的处理,这篇继续往下看。
注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。
一、initMessageSource(),这个方法是对spring的MessageSource初始化,代码如下:
1
2
3
4
5
6
7
|
ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//第1部分
} else {
//第2部分
} |
- 首先获取beanFactory对象,然后判断是否定义了名为messageSource的localbean,如果有则执行第1部分,否则执行第2部分,分别来看两部分代码
注:localbean实际上就是指查找的时候不会去parent查找这个bean,只从当前beanfactory去查找,很多地方有这个就不一一注明了
第1部分:
1
2
3
4
5
6
7
8
9
10
|
this .messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource. class );
if ( this .parent != null && this .messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this .messageSource;
if (hms.getParentMessageSource() == null ) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
} if (logger.isDebugEnabled()) {
logger.debug( "Using MessageSource [" + this .messageSource + "]" );
} |
- 第1行获取名为messageSource的bean赋值给当前ApplicationContext对象的messageSource属性
- 第2行判断如果当前ApplicationContext的parent不为null;并且messageSource对象继承了HierarchicalMessageSource接口则进行如下处理:
进行判断如果messageSource的parentMessageSource为空,则设置为getInternalParentMessageSource()方法的返回值。getInternalParentMessageSource()方法的代码也很简单
(getParent() instanceof AbstractApplicationContext) ? ((AbstractApplicationContext) getParent()).messageSource : getParent()
如果当前ApplicationContext的parent对象是AbstractApplicationContext或其子类类型则返回它的messageSource,否则直接返回其parent对象 - 最后是打印一行debug级别日志表示当前应用的messageSource
第2部分:
1
2
3
4
5
6
7
8
|
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource()); this .messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this .messageSource);
if (logger.isDebugEnabled()) {
logger.debug( "Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this .messageSource + "]" );
} |
- 第1行创建一个DelegatingMessageSource对象dms
- 第2行类似上面,设置dms的parentMessageSource为getInternalParentMessageSource()返回值
- 第3行设置当前ApplicationContext的messageSource属性为dms
- 第4行把这个对象注册一个名为messageSource的单例bean
- 打印一行debut日志表示无用户定义messageSource,使用默认
二、紧接着处理完messageSource的初始化后下一行代码:initApplicationEventMulticaster(),主要是对spring的事件监听器的管理器的初始话,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this .applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster. class );
if (logger.isDebugEnabled()) {
logger.debug( "Using ApplicationEventMulticaster [" + this .applicationEventMulticaster + "]" );
}
} else {
this .applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this .applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug( "Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this .applicationEventMulticaster + "]" );
}
} |
- 和messageSource的处理类似,首先取得beanFactory对象,
- 判断如果用户主动定义了applicationEventMulticaster的bean,则把这个bean设置给applicationEventMulticaster属性
- 如果没有则初始话一个默认的SimpleApplicationEventMulticaster,注册bean并赋值给对应属性
- 不同情况分别打印不同的日志,源代码中的日志打印最好也稍微注意一下有个印象,这样在看spring的日志时会更清晰
三、接下来是一个模板方法onRefresh(),第一篇中提到过这个是在处理messageSource、applicationEventMulticaster等特殊bean后,普通单例bean没初始话之前,为ApplicationContext子类提供扩展去处理一些类似的特殊bean。
举个例子AbstractRefreshableWebApplicationContext、GenericWebApplicationContext、StaticWebApplicationContext中都有一个themeSource,这个就要放在这个方法里去初始化。这个themeSource是spring的主题功能,可以实现根据不同主题加载不同资源文件等功能。
四、上面处理了事件监听器的管理器初始化,现在开始做时间监听器的注册:registerListeners(),这个方法的代码如下:
1
2
3
4
5
6
7
8
|
for (ApplicationListener listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
} String[] listenerBeanNames = getBeanNamesForType(ApplicationListener. class , true , false );
for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
} |
- 上面3行是处理当前ApplicationContext中的静态特殊监听器集合,循环调用applicationEventMulticaster的addApplicationListener()方法注册到applicationEventMulticaster中
- 后面的一部分首先取出所有类型为ApplicationListener的bean的name集合,然后循环调用applicationEventMulticaster的addApplicationListenerBean()方法注册到applicationEventMulticaster中
- 注意上面两个注册方法的不同,分别会注册到applicationEventMulticaster.defaultRetriever的不同集合中
本篇分别看到了messageSource、applicationEventMulticaster和applicationListener以及中间提到的主题themeSource的初始化,这里主要介绍初始话,所以后续再对spring的这几个功能模块做分别详细的分析。
refresh()方法中在上篇看完了MessageSource及时间监听器等初始话处理,这篇继续往下看。
注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。
一、finishBeanFactoryInitialization(beanFactory)这个方法将完成BeanFactory的初始化,主要做的事就是初始化除了之前处理过的特殊bean之外的所有单例bean,代码如下:
1
2
3
4
5
6
7
8
9
|
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService. class )) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService. class ));
} beanFactory.setTempClassLoader( null );
beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); |
- 第1-5行判断如果定义了名为conversionService并且类型为ConversionService的bean,则把其设置为beanFactory的conversionService属性。这个主要是用来提供数据转化服务的
- 销毁之前在prepareBeanFactory()中生成的临时ClassLoader
- freezeConfiguration()的代码如下:
1234
this
.configurationFrozen =
true
;
synchronized
(
this
.beanDefinitionMap) {
this
.frozenBeanDefinitionNames = StringUtils.toStringArray(
this
.beanDefinitionNames);
}
- 最后一行就是对所有非延迟加载的单例bean进行初始化了我们来看下这个方法的代码:
123456789101112131415161718192021222324252627282930
if
(
this
.logger.isInfoEnabled()) {
this
.logger.info(
"Pre-instantiating singletons in "
+
this
);
}
synchronized
(
this
.beanDefinitionMap) {
for
(String beanName :
this
.beanDefinitionNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if
(!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if
(isFactoryBean(beanName)) {
final
FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean
isEagerInit;
if
(System.getSecurityManager() !=
null
&& factory
instanceof
SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
new
PrivilegedAction<Boolean>() {
public
Boolean run() {
return
((SmartFactoryBean) factory).isEagerInit();
}
}, getAccessControlContext());
}
else
{
isEagerInit = factory
instanceof
SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();
}
if
(isEagerInit) {
getBean(beanName);
}
}
else
{
getBean(beanName);
}
}
}
}
首先获取bean定义信息对象bd,然后进行判断,这里只对非抽象bean(抽象bean是用于继承定义配置等信息的不可初始化)、单例、非延迟加载的bean进行处理
判断如果是FactoryBean则进行下面的处理,如果不是直接调用getBean(beanName),这个方法调用会进行这个bean的初始化,关于这个方法还是放到BeanFactory的单独分析里面这里就不往里看了。
对于FactoryBean的获取,要在beanname前加上一个&,然后会先判断是否是SmartFactoryBean并且渴望初始化(EagerInit),如果是才调用getBean(beanName),否则这个应该是在第一次调用工厂的getObject的时候才初始化
注:对于这中间AccessController.doPrivileged的运用没有搞明白,留待以后分析,不知道为什么要在这里使用这个
二、最后的一个处理是finishRefresh()方法,代码如下:
1
2
3
|
initLifecycleProcessor(); getLifecycleProcessor().onRefresh(); publishEvent( new ContextRefreshedEvent( this ));
|
1.先看initLifecycleProcessor()方法的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this .lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor. class );
if (logger.isDebugEnabled()) {
logger.debug( "Using LifecycleProcessor [" + this .lifecycleProcessor + "]" );
}
} else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this .lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this .lifecycleProcessor);
if (logger.isDebugEnabled()) {
logger.debug( "Unable to locate LifecycleProcessor with name '" +
LIFECYCLE_PROCESSOR_BEAN_NAME +
"': using default [" + this .lifecycleProcessor + "]" );
}
} |
这个方法主要是用来初始化生命周期管理器LifecycleProcessor的
- 如果用户定义了名为lifecycleProcessor类型为LifecycleProcessor的LocalBean,则赋值给当前ApplicationContext的lifecycleProcessor属性
- 如果用户没有定义,则初始化默认的生命周期管理器DefaultLifecycleProcessor,注册单例bean,并赋值给lifecycleProcessor属性
2.initLifecycleProcessor()方法之后则是对生命周期管理器的触发,LifecycleProcessor有两个触发点onRefresh()和onClose(),当前正处于refresh所以调用其onRefresh()方法
3.调用publishEvent()方法发布ContextRefreshedEvent事件,publishEvent()的代码也很简单就不介绍了,就是调用当前上下文及parent的ApplicationEventMulticaster的multicastEvent()方法,这个放到分析事件处理模块时再去详细分析。
三、最后分析一下在整个try代码块中如果抛出异常的处理,可以看到分为了两个方法调用:
1.destroyBeans()代码很简单,就是调用BeanFactory的destroySingletons()方法销毁所有单例bean。还是暂不细看放到BeanFactory专项分析里去
2.cancelRefresh()这个方法代码看一下:
1
2
3
|
synchronized ( this .activeMonitor) {
this .active = false ;
} |
就是在同步下设置状态值而已,但是有个小细节,这个方法在AbstractRefreshableApplicationContext和GenericApplicationContext两个子类中进行了重写,但是也很简单,就是增加了一个beanFactory.setSerializationId(null)然后依旧调用上面super中的方法进行修改状态
关于ApplicationContext的基本初始化的过车这就分析完了,中间碰到了很多问题,也还有很多地方需要详细研究,下面列举备忘一下,后面挨个分析:
- bean定义的加载
- bean的初始化
- BeanFactory的一些核心方法
- BeanFactory和ApplictionContext的关系以及各自的类继承框架
- 扩展点BeanFactoryPostProcessor及BeanPostProcessor
- 事件监听器ApplicationListener
- 信息管理器MessageSource
- 属性编辑器PropertyEditor
- 生命周期管理器LifecycleProcessor
- 还有几个小细节例如LoadTimeWeaver、MergedBeanDefinitionPostProcessor、AccessController.doPrivileged等
发表评论
-
spring知识
2012-08-13 13:20 941spring知识库url: http://spring.gro ... -
cxf 传递对象
2012-03-08 13:54 1983CXF框架简单的JavaBean对 ... -
WebService简介
2012-03-08 11:21 20341.1 WebService 简介 ... -
服务器启动时找不到org.springframework.web.ContextLoaderListener
2012-03-07 17:47 2427java.lang.NoClassDefFoundError: ... -
Could not find wsdl:binding operation info for web method sayHi
2012-03-07 17:34 7798spring cxf 异常: 有两个原因: 客 ... -
spring cxf 开发webservice
2012-03-07 17:30 1519CXF 与 spring 集成 1 . ... -
spring延迟初始化
2011-10-12 11:06 1337ApplicationContext实现的默 ... -
spring整合struts
2011-05-15 21:31 1279此篇文章为转载,留作记录,spring和struts1.X版本 ... -
spring注解
2011-05-15 10:47 1080概述 注释配置相对于 XML 配置具有很多的优势: 它可 ...
相关推荐
beanFactory.preInstantiateSingletons()的初始化过程详解,包含了所有的调用过程。
Spring 中控制 2 个 bean 的初始化顺序 在 Spring 框架中,控制多个 bean 的初始化顺序是一个常见的问题。本篇文章将详细介绍如何控制 2 个 bean 的初始化顺序,提供了多种实现方式,并分析了每种方式的优缺。 ...
Spring初始化参数的顺序是: 1. 对象初始化——构造方法 2. 对象初始化——`@PostConstruct`注解的方法 3. 对象初始化——实现了`InitializingBean`接口的`afterPropertiesSet`方法 4. 对象初始化——自定义的`init`...
在Spring框架中,Bean的创建和初始化是IoC(Inversion of Control)容器的核心功能,这一过程涉及到多个步骤。以下是对Spring Bean创建初始化流程的详细解释: 1. **初始化ApplicationContext**: 开始时,通过`...
在这个“干净的spring初始化工程”中,我们主要关注的是IOC和DI,而不涉及AOP。 **依赖注入(Dependency Injection,DI)**是Spring的核心特性之一,它简化了组件之间的依赖关系管理。在传统的Java应用中,对象通常...
"Spring初始化和销毁的实现方法" Spring框架中,Bean的初始化和销毁是非常重要的两个生命周期过程。今天我们将讨论Spring中 Bean 的初始化和销毁的实现方法。 1. 通过@Bean指定init-method和destroy-method 在 ...
那么Spring初始化的`Processor<T>`将会是`Processor<String>`: ```java Processor<String> processor = new Processor(); processor.service = new StringService(); ``` 如果`Service<T>`是`NumberService...
下面将详细介绍如何通过不同方式定义Spring Bean的初始化和销毁回调方法。 **初始化回调方法** 1. **@PostConstruct注解** 这个Java标准注解用于标记一个方法,该方法将在对象完全构造后但在业务逻辑执行前被调用...
在Spring框架中,Bean的初始化是一个至关重要的过程,它涉及到从XML配置文件或者注解中读取Bean的定义,解析并构建Bean实例。本篇文章主要分析了Spring如何通过`ClassPathXmlApplicationContext`来启动和初始化Bean...
### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能是IoC(Inversion of Control,控制反转)容器和AOP(Aspect Oriented ...
这就是基于注解的Spring初始化和依赖注入的基本原理,它极大地简化了代码,提高了可维护性,并且使得应用更易于测试。 总结一下,基于注解的Spring初始化主要涉及以下几点: 1. 使用`@Component`注解标记希望由...
Spring Bean的初始化和销毁实例详解 Spring Bean的初始化和销毁是Spring框架中一个非常重要的概念,它们都是Bean生命周期中不可或缺的一部分。在Spring框架中,我们可以使用多种方式来控制Bean的初始化和销毁,以下...
spring配置对象实例化后执行的方法,两种实现比对,通过InitializingBean接口,并实现arterPropertiesSet()方法;或者通过applicationContext.xml配置init-method属性
在Spring框架中,Bean的初始化是一个关键的概念,它涉及到Bean的生命周期管理以及Spring容器如何创建、配置和管理这些Bean。本文将深入探讨Spring容器中Bean的初始化过程。 首先,Spring容器根据XML配置文件(如`...
初始化后可访问Spring管理的Bean
在Spring MVC框架中,应用程序启动时会执行一系列初始化操作,这些操作对于理解Spring MVC的工作原理至关重要。本篇文章将深入探讨Spring MVC启动时初始化的几个常用方法,并解释它们在实际开发中的作用。 首先,...
三、Spring初始化过程 1. 创建Bean实例:根据Bean定义,Spring会创建Bean实例。如果配置了单例(singleton),那么Spring会缓存该Bean,后续请求将直接返回同一实例。 2. 属性注入:Spring会根据Bean定义中的属性...
这是一个重要的扩展点,因为Dubbo的一些组件,如`DubboConfigBean`,实际上就是`BeanFactoryPostProcessor`的实现,它会在Spring初始化完成后,进一步处理Dubbo相关的配置信息,比如服务提供者、消费者等信息的解析...