- 浏览: 329673 次
- 性别:
- 来自: 安徽
文章分类
最新评论
-
fanjf:
因为不是太懂,所以摘录!
DataStage---向目的库插入时出现问题:MLOG$ -
fanjf:
oracle 位图索引:位图索引: 解决某一表数据很多,但某一 ...
【转】 mysql 添加列,修改列,删除列。 -
fanjf:
创建索引:CREATE TABLE mm (m1 CHAR(1 ...
【转】 mysql 添加列,修改列,删除列。 -
fanjf:
查询mysql 的表emp 的约束:
SELECT * FR ...
【转】 mysql 添加列,修改列,删除列。 -
fanjf:
为什么 update 不报错,结果为空?
关于MYSQL 检查check约束
开篇先用一张老图描述下 Spring 中 Bean 容器的生命周期。
插叙一下,记得某个博文中提到:“ Spring 的 Bean 容器只管理非单例 Bean 的生命周期,单例 Bean 的生命周期不在管理范围内”,其实我认为这句话恰好说反了。首先明确一点,并非 Spring 容器中所有的 Bean 都有生命周期行为,只有接受容器管理生命周期的 Bean 才具有生命周期行为:而单例( Singleton ) Bean 接受容器管理,非单例( non-singleton ) Bean 在实例化后,完全交给了客户端代码管理,容器不再跟踪其生命周期,每次客户请求,容器都会创建一个新的实例,所以 Spring 容易无法知晓 Bean 何时销毁。
继续刚才的话题—— Bean 容器的生命周期。其实上图有个节点没有画出,就是在实例化所有 Bean 之前会执行 BeanFactoryPostProcessors 。不过也不 care ,因为这和 Bean 的生命周期没有太大关系,所以没有提及也属正常,权且忽略该节点。
从图中,我们可以看到实例化 Bean 的过程中有以下几个节点:
1)设置属性值;
2)调用 Bean 中的 BeanNameAware.setBeanName() 方法,如果该 Bean 实现了 BeanNameAware 接口;
3)调用 Bean 中的 BeanFactoryAware.setBeanFactory() 方法,如果该 Bean 实现了 BeanFactoryAware 接口;
4)调用 BeanPostProcessors. postProcessBeforeInitialization () 方法;
5)调用 Bean 中的 afterPropertiesSet 方法,如果该 Bean 实现了 InitializingBean 接口;
6)调用 Bean 中的 init-method ,通常是在配置 bean 的时候指定了 init-method ,例如: <bean class="beanClass" init-method="init" ></bean>
7)调用 BeanPostProcessors. postProcess After Initialization () 方法;
8)如果该 Bean 是单例的,则当容器销毁并且该 Bean 实现了 DisposableBean 接口的时候,调用 destory 方法;如果该 Bean 是 prototype ,则将准备好的 Bean 提交给调用者,后续不再管理该 Bean 的生命周期。
好了,简单了描述了下那幅图。一切都还太抽象了,作为程序员,代码还是最直接的表达方式。那我们就一起看段演示代码吧。
首先,为达到演示效果,我们准备两个待测试的 Bean ,代码如下:
- @Component
- public class DemoBean implements BeanFactoryAware, BeanNameAware,
- InitializingBean, DisposableBean {
- @PostConstruct
- public void init() {
- System.out.println( "DemoBean: init-method" );
- }
- public void destroy() throws Exception {
- System.out.println( "DemoBean: destroy-method!" );
- }
- public void afterPropertiesSet() throws Exception {
- System.out.println( "DemoBean: after properties set!" );
- }
- public void setBeanName(String name) {
- System.out.println( "DemoBean: beanName aware, [name=" + name + "]" );
- }
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- System.out.println( "DemoBean: beanFactory aware, [beanFactory=" + beanFactory.toString() + "]" );
- }
- }
- public class AnotherDemoBean implements InitializingBean {
- @PostConstruct
- public void postConstruct() {
- System.out.println( "AnotherDemoBean: postConstruct-method" );
- }
- public void init() {
- System.out.println( "AnotherDemoBean: init-method" );
- }
- @Override
- public void afterPropertiesSet() throws Exception {
- System.out.println( "AnotherDemoBean: after properties set!" );
- }
- }
上面两个 Bean 大致相同,区别在于第一个 Bean 使用注解方式注入,第二个 Bean 我们使用配置文件方式,并指定其 init-method ,用于观察 init-method 与 postConstruct 的执行先后。
我们这个演示 Bean 实现了 BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean 这几个接口,其实这些接口也可理解为 Spring 容器的一个个扩展点。
然后,我们再编写一个 BeanPostProcessor ,用于演示生命周期中的步骤 4 和步骤 7 。 代码如下:
- @Component
- public class DemoBeanPostProcessor implements BeanPostProcessor {
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- System.out.println( "DemoBeanPostProcessor: post process before initialization, [beanName=" + beanName + ", bean=" + bean + "]" );
- return bean;
- }
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- System.out.println( "DemoBeanPostProcessor: post process before initialization, [beanName=" + beanName + ", bean=" + bean + "]" );
- return bean;
- }
- }
最后,我们编写测试类,以及 Spring 的配置文件,这里我们使用 ClassPathXMLApplicationContext 加载配置文件和初始化 Spring 容器。一起看下配置文件和测试类代码:
applicationContext.xml:
- <? xml version = "1.0" encoding = "GBK" ?>
- < beans xmlns = "http://www.springframework.org/schema/beans"
- xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:aop = "http://www.springframework.org/schema/aop"
- xmlns:context = "http://www.springframework.org/schema/context" xmlns:tx = "http://www.springframework.org/schema/tx"
- xsi:schemaLocation ="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" >
- < context:component-scan base-package = "com.shansun.multidemo" > </ context:component-scan >
- < bean class = "com.shansun.multidemo.spring.lifecycle.AnotherDemoBean" init-method = "init" > </ bean >
- </ beans >
Main.java
- public class Main {
- @SuppressWarnings ( "unused" )
- public static void main(String[] args) {
- ApplicationContext ctx = new ClassPathXmlApplicationContext( "applicationContext.xml" );
- }
- }
好了,一切就绪,我们就静观程序输出吧:
- DemoBean: beanName aware, [name=demoBean]
- DemoBean: beanFactory aware, [beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory @888e6c :defining beans [demoBean,demoBeanFactoryPostProcessor,demoBeanPostProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,com.shansun.multidemo.spring.lifecycle.AnotherDemoBean# 0 ]; root of factory hierarchy]
- DemoBean: init-method
- DemoBeanPostProcessor: post process before initialization, [beanName=demoBean, bean=com.shansun.multidemo.spring.lifecycle.DemoBean @1deeb40 ]
- DemoBean: after properties set!
- DemoBeanPostProcessor: post process before initialization, [beanName=demoBean, bean=com.shansun.multidemo.spring.lifecycle.DemoBean @1deeb40 ]
- AnotherDemoBean: postConstruct-method
- DemoBeanPostProcessor: post process before initialization, [beanName=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean# 0 , bean=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean @1a7ddcf ]
- AnotherDemoBean: after properties set!
- AnotherDemoBean: init-method
- DemoBeanPostProcessor: post process before initialization, [beanName=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean# 0 , bean=com.shansun.multidemo.spring.lifecycle.AnotherDemoBean @1a7ddcf ]
和我们预期的是否一样呢?是的。观察结果发现一个有趣的地方:在配置文件中指定的 init-method 和使用 @PostConstruct 注解的方法,孰先孰后呢,两者是否等同呢? 后续我将通过分析源码给出结论 。
我们通过演示代码也验证了 Bean 容器的生命周期,但是还缺点什么吧。对了,透过 Spring 源码讲述 Bean 容器的生命周期是否更加直观和令人信服呢?下面我们去 Spring 源码中一探究竟。这里我们选用的是 spring-2.5.6.SEC02 。
大家应该都知道 Spring 中 BeanFactory 和 ApplicationContext 的关系了吧, ApplicationContext 继承自 BeanFactory ,所以可以操作到 bean 。更详细的内容可以参考许令波同学的《 Spring 框架的设计理念与设计模式分析》,里面有较清晰的分析。
好了,闲话不多说。
首先,我们探视下实例化 Bean 的方法 initializeBean ,该方法在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 类下,一起看下该段代码:
- protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
- if (bean instanceof BeanNameAware) {
- ((BeanNameAware) bean).setBeanName(beanName);
- }
- if (bean instanceof BeanClassLoaderAware) {
- ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
- }
- if (bean instanceof BeanFactoryAware) {
- ((BeanFactoryAware) bean).setBeanFactory( this );
- }
- Object wrappedBean = bean;
- if (mbd == null || !mbd.isSynthetic()) {
- wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
- }
- try {
- invokeInitMethods(beanName, wrappedBean, mbd);
- }
- catch (Throwable ex) {
- throw new BeanCreationException(
- (mbd != null ? mbd.getResourceDescription() : null ),
- beanName, "Invocation of init method failed" , ex);
- }
- if (mbd == null || !mbd.isSynthetic()) {
- wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
- }
- return wrappedBean;
- }
这样够直观了吧,是不是和前文描述的一样呢, J
本文源代码下载: https://lb-multi-demo.googlecode.com/svn/trunk/spring-lifecycle-test
发表评论
-
org.springframework.dao.DataAccessResourceFailureException Io 异常: tConnection re
2014-02-14 11:05 2360最近程序老是出现等待一会后 操作程序页面 出现下面异常 ... -
MyBatis3整合Spring3的Transaction事务处理
2012-03-19 10:48 978正如第二版,Spring 仅支持 iBatis2。那么我们就想 ... -
MyBatis3整合Spring3、SpringMVC3
2012-03-19 10:47 1136开发环境: System:Windows ... -
FreeMarker配置详解
2012-03-16 16:52 2147<? xml version="1.0&qu ... -
FreeMarker整合Spring 3.0
2012-03-16 16:39 959开发环境: System:Windows We ... -
Spring 的AOP(面向切面编程)
2012-03-05 17:59 984AOP 是一门编程技术, spring 的 ... -
spring 配置完Service怎么得到Action
2012-02-29 16:36 1326写一个手机发送短信的后台处理在包装短信时,今天遇到一个问题: ... -
Spring的优点:
2012-02-21 19:28 803Spring带给我们什么: ◆方便解耦,简化开发 ... -
Spring中两种注入方式的对比
2012-02-21 19:26 1267spring依赖注入的两种方式: 1.设置注入; 2.构造 ... -
spring中bean继承与java继承的区别
2012-02-21 19:25 9051.Spring中子bean和父bean可以是不同类型,jav ... -
spring依赖关系配置
2012-02-21 19:25 1024依赖注入--如果A依赖于B,则B实例不再由A负责生成,而有容器 ... -
Spring 依赖检查
2012-02-21 19:24 910在进行说明bean依赖检查的几种模式前,先给大家说明我们为什么 ... -
Spring内核研究-管理bean的声明周期一(InitializingBean和init-method)
2012-02-20 10:01 1095... -
源码解析:init-method、@PostConstruct、afterPropertiesSet孰先孰后
2012-02-15 17:25 1561Spring 容器中的 Bean ... -
Spring的InitializingBean和init-method
2012-02-15 17:24 938Spring在设置完一个bean所有的属性后,会检查bean是 ... -
Spring的init-method 与afterPropertiesSet
2012-02-15 17:22 1384init-method 与afterPropertiesSet ... -
Spring事务配置的五种方式
2012-02-15 16:55 718前段时间对Spring的事务配置做了比较深入的研究,在此之间对 ...
相关推荐
- **XML配置**:在传统的Spring应用中,Bean的定义通常写在XML配置文件中,如`springbean-xml`中的配置。 - **注解配置**:使用`@Component`,`@Service`,`@Repository`和`@Controller`注解标记类,配合`@...
接下来,我们将深入探讨Spring Bean生命周期的各个阶段,并通过具体的示例来演示。 1. **配置阶段** 在Spring容器初始化时,它会读取配置文件(如XML或Java配置),解析Bean定义,包括其依赖关系、初始化方法、...
其中,Spring Bean生命周期的管理是Spring框架的核心功能之一,它涉及Spring容器如何创建、配置以及销毁Bean的整个过程。理解Spring Bean的生命周期对于开发高效和可维护的Java应用至关重要。 Spring Bean生命周期...
Spring Bean 生命周期是 Spring 框架中的一个核心概念,了解 Spring Bean 的生命周期对我们了解整个 Spring 框架会有很大的帮助。本文将详细介绍 Spring Bean 生命周期的概念、生命周期图、生命周期阶段、生命周期...
Spring中Bean的生命周期和作用域及实现方式 Spring是一个非常流行的Java应用程序框架,它提供了一个灵活的机制来管理Bean的生命周期和作用域。Bean的生命周期和作用域是Spring框架中两个非常重要的概念,它们决定了...
本资源提供了在Spring 4.2环境下关于Bean生命周期的测试代码,帮助我们深入理解这一关键概念。 首先,让我们了解Spring Bean的生命周期主要包含以下几个阶段: 1. **实例化**:Spring容器通过`Class`对象或`...
SpringBean的生命周期.mdj
Spring框架是Java应用开发中的一个核心组件,尤其在企业级应用中广泛使用。Spring通过其IoC(Inversion of Control,控制反转)容器管理Bean的生命周期,...理解Bean生命周期对于有效管理和优化Spring应用至关重要。
Bean生命周期的理解对于优化应用性能和理解Spring内部工作原理至关重要。这里我们将深入探讨Spring的Bean生命周期、容器周期以及工厂周期。 首先,让我们从Bean生命周期开始。在Spring中,Bean的生命周期包括以下几...
本篇将详细阐述Spring Bean生命周期的各个阶段,以及如何记忆和深入理解这一过程。 首先,Spring Bean的生命周期可以分为两个主要阶段:容器初始化阶段和容器销毁阶段。 在容器初始化阶段,Spring Bean会经历以下...
在Spring框架中,Bean生命周期是核心概念之一,它涉及到Bean的创建、初始化、使用和销毁等阶段。了解和掌握Bean生命周期对于开发高质量的Spring应用至关重要。以下是对Spring Bean生命周期的详细解析。 首先,Bean...
在Spring框架中,Bean的生命周期管理和ApplicationContext的应用是两个核心概念,它们对于理解Spring如何管理和协调应用中的对象至关重要。本文将深入探讨这两个主题,并结合国际化(i18n)和事件传递来阐述它们在...
在Spring框架中,Spring Bean的生命周期始于其创建过程,即"我从哪里来?"的问题。首先,要明确几个核心概念:Java Bean、Spring Bean和Spring IoC(控制反转)容器。Java Bean是一种遵循特定规范的Java类,而Spring...
Spring中的Bean生命周期主要分为两个阶段:容器管理阶段和用户自定义阶段。在容器管理阶段,Spring容器负责Bean的实例化、属性注入、初始化、使用和销毁。而在用户自定义阶段,开发者可以通过定义回调方法或使用特定...
这两个后处理器接口提供了灵活的扩展点,允许开发者在Bean生命周期的关键点进行自定义操作。 ApplicationContext是BeanFactory的升级版,提供了更丰富的功能,包括事件发布、国际化等。在ApplicationContext中,...
下面以一个简单的Person类为例,展示Spring Bean生命周期的各个阶段: ```java public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { // 省略属性和构造器 @...
在Spring框架中,在IOC容器中管理的Bean分为单例和原型两种,单例Bean在容器启动时就实例化,原型Bean则是每次从容器中请求时才会实例化。
一旦XML配置加载到Spring容器中,容器将根据配置创建Bean实例,并按照定义进行初始化、依赖注入,最后完成Bean的生命周期管理。 10. **实践操作**: 在实际开发中,我们可以使用Eclipse的Spring插件来简化Bean...
解决这个问题的关键在于深入理解Spring的Bean生命周期和配置机制,检查配置文件、注解使用、依赖关系等,确保每个Bean的定义都是唯一的,且作用域设置正确。同时,对源码进行调试也是一个有效的排查手段,可以追踪到...