`
java-mans
  • 浏览: 11710402 次
文章分类
社区版块
存档分类
最新评论

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>

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

装配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