`
dwj147258
  • 浏览: 191770 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Spring执行吧bean初始化方法的两种方式

阅读更多

InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。

测试程序如下:

1
2
3
4
5
6
7
8
9
10
import org.springframework.beans.factory.InitializingBean;
public class TestInitializingBean implements InitializingBean{
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("ceshi InitializingBean");        
    }
    public void testInit(){
        System.out.println("ceshi init-method");        
    }
}

配置文件如下:

1
<bean id="testInitializingBean" class="com.TestInitializingBean" ></bean>

Main主程序如下:

1
2
3
4
5
public class Main {
    public static void main(String[] args){
        ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/com/beans.xml");
    }
}

运行Main程序,打印如下结果:

1
ceshi InitializingBean

这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。

问题

实现InitializingBean接口与在配置文件中指定init-method有什么不同?

修改配置文件,加上init-method配置,修改如下:

1
<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>

在配置文件中加入init-method="testInit"。

运行Main程序,打印如下结果:

1
2
ceshi InitializingBean
ceshi init-method

由结果可看出,在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。

这方式在spring中是怎么实现的?

通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙

AbstractAutowireCapableBeanFactory类中的invokeInitMethods讲解的非常清楚,源码如下:

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
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
    //判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
         
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                    public Object run() throws Exception {
                        //直接调用afterPropertiesSet
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }
                },getAccessControlContext());
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }                
        else {
            //直接调用afterPropertiesSet
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }
    if (mbd != null) {
        String initMethodName = mbd.getInitMethodName();
        //判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method
        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            //进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

总结

1:spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用

2:实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖

3:如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。

分享到:
评论

相关推荐

    详解Spring 中如何控制2个bean中的初始化顺序

    除了上述两种方式外,还有其他方式可以控制 2 个 bean 的初始化顺序。例如,可以使用 Spring 的 @Order 注解来指定 bean 的初始化顺序,也可以使用 Spring 的生命周期接口(如 InitializingBean)来控制 bean 的初始...

    Spring Bean的初始化和销毁实例详解

    在Spring框架中,我们可以使用多种方式来初始化Bean,下面我们将介绍两种常见的方式: 1、使用@Bean的initMethod 在使用@Bean注解时,我们可以使用initMethod属性来指定Bean的初始化方法。例如: ```java @Bean...

    实例化Spring bean的两种工厂方法

    本篇将详细探讨两种工厂方法——实例工厂方法和静态工厂方法,用于创建Spring Bean。 首先,我们要理解Spring Bean的概念。Spring Bean是Spring IoC容器管理的对象,这些对象的生命周期、依赖关系以及初始化行为由...

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

    3. **初始化**:在实例化和属性注入后,Spring调用Bean的初始化回调方法。这些方法可以通过以下方式定义: - `@PostConstruct`注解的方法:当容器调用该注解的方法时,表明Bean的初始化完成。 - `InitializingBean...

    Spring中与Bean相关的接口

    它提供两个方法:`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`,分别在Bean初始化之前和之后调用,可以用来进行额外的处理或校验。 在Bean的定义中,我们可以使用`@Component`、`@...

    Spring的IoC容器初始化源码解析

    ### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能是IoC(Inversion of Control,控制反转)容器和AOP(Aspect Oriented ...

    spring bean的生命周期

    - **初始化回调**:Spring支持两种类型的初始化回调方法,即`@PostConstruct`注解的方法和在XML中定义的`init-method`属性指定的方法。 2. **容器管理的生命周期回调** - **Singleton Beans的懒加载**:如果Bean...

    Spring管理的Bean的生命周期

    2. **BeanPostProcessor接口**:实现这个接口的类可以定义两个方法`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`,分别在Bean初始化前和后进行处理。 3. **@PostConstruct注解**:在...

    Spring bean 管理

    Spring支持通过XML配置文件使用构造函数注入和setter方法注入两种属性注入方式。 - 构造函数注入:在元素中声明的属性,通过构造函数传递给Bean实例。 - setter方法注入:通过元素设置的属性,Spring调用相应的...

    Java中Spring获取bean方法小结

    获取Bean的两种常见方式是: - 使用`FileSystemXmlApplicationContext`,从文件系统加载配置文件。 - 使用`ClassPathXmlApplicationContext`,从类路径加载配置文件。例如: ```java ApplicationContext context...

    spring创建bean简单示例

    Spring允许我们定义Bean的生命周期,如初始化方法和销毁方法。使用`@PostConstruct`和`@PreDestroy`注解来指定这些方法。 ```java @Service public class MyService { @PostConstruct public void init() { // ...

    Spring的Bean配置

    1. **XML配置**:传统的Spring配置通常使用XML文件,如`beans.xml`,其中包含了Bean的定义,包括类名、初始化方法、属性等。例如: ```xml &lt;bean id="exampleBean" class="com.example.ExampleClass"&gt; ...

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

    3. **初始化回调**:在属性注入完成后,Spring会调用Bean的初始化方法。如果在Bean定义中配置了`init-method`,那么这个方法会被执行。此外,实现`InitializingBean`接口的Bean也会自动调用`afterPropertiesSet()`...

    深度解析spring容器管理bean

    初始化回调是指在Bean实例化后、开始使用前执行的方法,可以通过`init-method`属性指定。销毁回调则是在Bean不再使用、即将被销毁时调用的方法,可通过实现DisposableBean接口或`destroy-method`属性设置。 此外,...

    Spring之核心容器bean

    你可以为bean定义初始化方法和销毁方法,容器会在适当的时候调用。此外,还可以通过实现InitializingBean和DisposableBean接口,或者使用`@PostConstruct`和`@PreDestroy`注解来定义生命周期行为。 **自动装配...

    Spring高级应用,Bean讲解

    在 Spring 中,可以使用 `init-method` 和 `destroy-method` 属性来指定 Bean 的初始化和销毁方法。 Bean 是 Spring 框架中的核心组件,理解 Bean 的概念、配置、实例化和生命周期是使用 Spring 框架的基础。

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

    该接口包含两个方法:`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`,这两个方法会在Bean初始化的相应阶段被调用。 总的来说,Spring Bean的生命周期包括实例化、初始化、使用和销毁等...

    springboot初始化资源的几种方式源码

    当我们需要在bean初始化后执行特定的代码时,可以使用`@PostConstruct`注解。这个注解标记的方法会在bean实例化并且所有依赖注入完成后调用。例如: ```java @Component public class AppConfig { @...

    spring 中特殊bean用法

    9. **Bean后处理器(Bean Post Processor)**: Bean后处理器允许在初始化Bean之后和销毁Bean之前执行自定义逻辑。通过实现`BeanPostProcessor`接口,我们可以自定义Bean的初始化和销毁行为。 10. **Resource注入**:...

Global site tag (gtag.js) - Google Analytics