`
fanjf
  • 浏览: 332762 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

Spring内核研究-管理bean的声明周期一(InitializingBean和init-method)

 
阅读更多

Spring内核研究-管理bean的声明周期一(InitializingBean和init-method)

InitializingBean

    Spirng的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。

Bean实现这个接口,在afterPropertiesSet()中编写初始化代码:
package research.spring.beanfactory.ch4; import org.springframework.beans.factory.InitializingBean; public class LifeCycleBean implements InitializingBean{ public void afterPropertiesSet() throws Exception { System. out .println( " LifeCycleBean initializing... " ); } }
 
在xml配置文件中并不需要对bean进行特殊的配置:
xml version="1.0" encoding="UTF-8" ?> DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="lifeBean" class ="research.spring.beanfactory.ch4.LifeCycleBean" > bean > beans >

 
编写测试程序进行测试:
package research.spring.beanfactory.ch4; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; public class LifeCycleTest { public static void main(String[] args) { XmlBeanFactory factory = new XmlBeanFactory( new ClassPathResource( " research/spring/beanfactory/ch4/context.xml " )); factory.getBean( " lifeBean " ); } }

    运行上面的程序我们会看到:“LifeCycleBean initializing...”,这说明bean的afterPropertiesSet已经被Spring调用了。
 
    Spring在设置完一个bean所有的合作者后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。

 SHAPE  \* MERGEFORMAT

装配bean 的合作者

查看bean 是否实现 InitializingBean接口

调用afterPropertiesSet 方法


init-method

    Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起 了。通常情况下我不鼓励bean直接实现InitializingBean,可以使用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法。
写一个java class,这个类不实现任何Spring的接口。定义一个没有参数的方法init()。
package research.spring.beanfactory.ch4; public class LifeCycleBean{ public void init(){ System. out .println( " LifeCycleBean.init... " ); } }
 
在Spring中配置这个bean:
xml version="1.0" encoding="UTF-8" ?> DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="lifeBean" class ="research.spring.beanfactory.ch4.LifeCycleBean"  init-method ="init" > bean > beans >

当Spring实例化lifeBean时,你会在控制台上看到” LifeCycleBean.init...”。
 
 
Spring要求init-method是一个无参数的方法,如果init-method指定的方法中有参数,那么Spring将会抛出java.lang.NoSuchMethodException
 
init-method指定的方法可以是public、protected以及private的,并且方法也可以是final的。
 
init-method指定的方法可以是声明为抛出异常的,就像这样:

       final protected void init() throws Exception{

           System.out.println("init method...");

           if(true) throw new Exception("init exception");

    }
如果在init-method方法中抛出了异常,那么Spring将中止这个Bean的后续处理,并且抛出一个org.springframework.beans.factory.BeanCreationException 异常。
 
InitializingBean和init-method可以一起使用,Spring会先处理InitializingBean再处理init-method。
org.springframework.beans.factory.support. AbstractAutowireCapableBeanFactory完成一个Bean初始化方法的调用工作。 AbstractAutowireCapableBeanFactory是XmlBeanFactory的超类,再 AbstractAutowireCapableBeanFactory的invokeInitMethods方法中实现调用一个Bean初始化方法:
org.springframework.beans.factory.support. AbstractAutowireCapableBeanFactory.java:
// …… // 在一个bean的合作者设备完成后,执行一个bean的初始化方法。 protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mergedBeanDefinition)  throws Throwable { // 判断bean是否实现了InitializingBean接口 if (bean instanceof InitializingBean) { if (logger.isDebugEnabled()) { logger.debug( " Invoking afterPropertiesSet() on bean with name ‘ " + beanName + " " ); } // 调用afterPropertiesSet方法 ((InitializingBean) bean).afterPropertiesSet(); } // 判断bean是否定义了init-method if (mergedBeanDefinition != null && mergedBeanDefinition.getInitMethodName() != null ) { // 调用invokeCustomInitMethod方法来执行init-method定义的方法 invokeCustomInitMethod(beanName, bean, mergedBeanDefinition.getInitMethodName()); } } // 执行一个bean定义的init-method方法 protected void invokeCustomInitMethod(String beanName, Object bean, String initMethodName) throws Throwable { if (logger.isDebugEnabled()) { logger.debug( " Invoking custom init method ‘ " + initMethodName + " ‘ on bean with name ‘ " + beanName + " " ); } // 使用方法名,反射Method对象 Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null ); if (initMethod == null ) { throw new NoSuchMethodException( " Couldn‘t find an init method named ‘ " + initMethodName + " ‘ on bean with name ‘ " + beanName + " " ); } // 判断方法是否是public if ( ! Modifier.isPublic(initMethod.getModifiers())) { // 设置accessible为true,可以访问private方法。 initMethod.setAccessible( true ); } try { // 反射执行这个方法 initMethod.invoke(bean, (Object[]) null ); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } // ………..

    通过分析上面的源代码我们可以看到,init-method是通过反射执行的,而afterPropertiesSet是直接执行的。所以 afterPropertiesSet的执行效率比init-method要高,不过init-method消除了bean对Spring依赖。在实际使 用时我推荐使用init-method。
    需要注意的是Spring总是先处理bean定义的InitializingBean,然后才处理init-method。如果在Spirng处理InitializingBean时出错,那么Spring将直接抛出异常,不会再继续处理init-method。
    如果一个bean被定义为非单例的,那么afterPropertiesSet和init-method在bean的每一个实例被创建时都会执行。单例 bean的afterPropertiesSet和init-method只在bean第一次被实例时调用一次。大多数情况下 afterPropertiesSet和init-method都应用在单例的bean上。

分享到:
评论

相关推荐

    Spring的InitializingBean和init-method

    本文将深入探讨Spring中的`InitializingBean`接口和`init-method`属性,这两个特性都与bean的初始化过程密切相关。 `InitializingBean`是Spring框架提供的一种回调机制,用于在bean实例化后进行额外的初始化工作。...

    详解Spring中Bean的生命周期和作用域及实现方式

    Spring是一个非常流行的Java应用程序框架,它提供了一个灵活的机制来管理Bean的生命周期和作用域。Bean的生命周期和作用域是Spring框架中两个非常重要的概念,它们决定了Bean的生命周期和作用域的管理方式。 一、...

    Spring bean生命周期demo

    不同作用域的Bean,其生命周期和管理方式也不同。例如,单例Bean在整个应用中只有一个实例,而原型Bean每次请求都会创建新的实例。 6. **AOP代理** 如果Bean被声明为需要AOP代理(例如,带有切面注解),Spring会...

    Spring bean 管理

    Spring的核心之一是Spring容器,它负责管理应用程序中所有组件的生命周期和依赖关系。Spring容器中最为常见的组件是Bean,它是Spring容器管理的对象实例。 在Spring中,Bean的管理包含多个方面:创建Bean实例、配置...

    Spring Bean生命周期&BeanDefinitions1

    Spring框架是Java应用开发中的一个核心组件,尤其在企业级应用中广泛使用。Spring通过其IoC(Inversion of Control,控制反转)容器管理Bean的生命周期,...理解Bean生命周期对于有效管理和优化Spring应用至关重要。

    Spring Bean生命周期.pdf

    其中,Spring Bean生命周期的管理是Spring框架的核心功能之一,它涉及Spring容器如何创建、配置以及销毁Bean的整个过程。理解Spring Bean的生命周期对于开发高效和可维护的Java应用至关重要。 Spring Bean生命周期...

    spring入门学习-3、Bean装配(XML).pdf

    Spring提供了多种作用域,如`singleton`、`prototype`等,不同的作用域决定了Bean的生命周期和创建策略。 4. **Constructor-arguments**:用于通过构造器注入依赖关系。这种方式通常用于必填的依赖项。 5. **...

    Spring part 2 :Bean的生命周期

    Spring提供两种方式来管理Bean的生命周期:编程式和声明式。编程式通过实现接口如InitializingBean和DisposableBean,然后重写其特定方法(afterPropertiesSet()和destroy())来控制Bean的初始化和销毁。声明式则是...

    Spring框架中Bean的生命周期 Spring中Bean有几种作用域

    在Spring框架中,Bean的生命周期管理和作用域是其核心特性之一,它们对于理解Spring如何管理对象的创建、初始化、使用以及销毁至关重要。首先,我们来深入探讨Bean的生命周期。 Spring中的Bean生命周期主要分为两个...

    基于java的企业级应用开发:Bean的生命周期.ppt

    在企业级应用开发中,Java和Spring框架是广泛使用的工具,尤其在管理Bean的生命周期方面。理解Bean的生命周期对于优化应用程序性能和实现高效资源管理至关重要。以下是对标题和描述中涉及知识点的详细说明: 1. **...

    Spring管理的Bean的生命周期

    总之,Spring管理的Bean生命周期包括创建、初始化、活跃使用和销毁四个主要阶段,通过各种回调方法、接口和注解,我们可以对Bean的行为进行自定义,以满足不同应用场景的需求。深入理解这些机制,有助于我们更好地...

    spring bean life cycle

    在Spring框架中,Bean生命周期是核心概念之一,它涉及到Bean的创建、初始化、使用和销毁等阶段。了解和掌握Bean生命周期对于开发高质量的Spring应用至关重要。以下是对Spring Bean生命周期的详细解析。 首先,Bean...

    Spring的bean生命周期

    3. **初始化**:初始化阶段,Spring允许开发者定义初始化方法,如通过@Bean的initMethod属性指定,或者在Bean实现InitializingBean接口并重写afterPropertiesSet()方法。此外,还可以使用@PostConstruct注解标记的...

    Spring中Bean的生命周期 applicationcontext的应用(实现国际化,事件的传递)

    总的来说,理解并熟练运用Spring中Bean的生命周期和ApplicationContext,能帮助开发者更高效地设计和维护Spring应用,同时利用国际化和事件传递提高应用的灵活性和可扩展性。在实践中,这些概念和机制是构建复杂、...

    spring-hook-test.rar

    4. **注解驱动编程**:Spring Boot鼓励使用注解来声明Bean、依赖注入、配置等,例如`@Component`、`@Service`、`@Repository`和`@Controller`用于声明不同角色的Bean,`@Autowired`用于自动装配依赖,以及`@Value`...

    Spring Bean 生命周期之“我从哪里来?”.docx

    Java Bean是一种遵循特定规范的Java类,而Spring Bean是在Spring IoC容器管理下的Java Bean,具有更丰富的管理和装配能力。 Spring IoC容器是整个流程的核心,它负责创建、配置和管理Bean。容器通过解析配置元数据...

    Spring--2.Spring 中的 Bean 配置-2-2

    在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、依赖注入以及生命周期管理。在"Spring--2.Spring 中的 Bean 配置-2-2"这个主题下,我们将深入探讨如何在Spring中进行Bean的详细配置。 1. **...

    spring的bean加载顺序样例项目

    在Spring框架中,Bean的加载顺序是一个重要的概念,它涉及到Spring容器如何管理和初始化Bean的过程。在"spring的bean加载顺序样例项目"中,我们可以通过分析和实验来深入理解这一主题。下面将详细阐述Spring Bean的...

    day38 09-Spring类的完整生命周期及后处理Bean

    Bean可以通过实现InitializingBean接口并覆盖`afterPropertiesSet()`方法,或者定义一个`init-method`属性指定初始化方法。此外,如果Bean实现了ApplicationContextAware接口,Spring会在初始化时注入...

    spring-spring-framework-4.3.24.RELEASE.zip

    1. **IoC(Inversion of Control)容器**:Spring的核心是IoC容器,它负责管理对象的生命周期和依赖关系。通过XML配置或注解方式,开发者可以声明对象及其依赖,由容器负责实例化、装配和管理。在源码中,`org....

Global site tag (gtag.js) - Google Analytics