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指定的方法。
相关推荐
除了上述两种方式外,还有其他方式可以控制 2 个 bean 的初始化顺序。例如,可以使用 Spring 的 @Order 注解来指定 bean 的初始化顺序,也可以使用 Spring 的生命周期接口(如 InitializingBean)来控制 bean 的初始...
在Spring框架中,我们可以使用多种方式来初始化Bean,下面我们将介绍两种常见的方式: 1、使用@Bean的initMethod 在使用@Bean注解时,我们可以使用initMethod属性来指定Bean的初始化方法。例如: ```java @Bean...
本篇将详细探讨两种工厂方法——实例工厂方法和静态工厂方法,用于创建Spring Bean。 首先,我们要理解Spring Bean的概念。Spring Bean是Spring IoC容器管理的对象,这些对象的生命周期、依赖关系以及初始化行为由...
3. **初始化**:在实例化和属性注入后,Spring调用Bean的初始化回调方法。这些方法可以通过以下方式定义: - `@PostConstruct`注解的方法:当容器调用该注解的方法时,表明Bean的初始化完成。 - `InitializingBean...
它提供两个方法:`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`,分别在Bean初始化之前和之后调用,可以用来进行额外的处理或校验。 在Bean的定义中,我们可以使用`@Component`、`@...
### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能是IoC(Inversion of Control,控制反转)容器和AOP(Aspect Oriented ...
- **初始化回调**:Spring支持两种类型的初始化回调方法,即`@PostConstruct`注解的方法和在XML中定义的`init-method`属性指定的方法。 2. **容器管理的生命周期回调** - **Singleton Beans的懒加载**:如果Bean...
2. **BeanPostProcessor接口**:实现这个接口的类可以定义两个方法`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`,分别在Bean初始化前和后进行处理。 3. **@PostConstruct注解**:在...
Spring支持通过XML配置文件使用构造函数注入和setter方法注入两种属性注入方式。 - 构造函数注入:在元素中声明的属性,通过构造函数传递给Bean实例。 - setter方法注入:通过元素设置的属性,Spring调用相应的...
获取Bean的两种常见方式是: - 使用`FileSystemXmlApplicationContext`,从文件系统加载配置文件。 - 使用`ClassPathXmlApplicationContext`,从类路径加载配置文件。例如: ```java ApplicationContext context...
Spring允许我们定义Bean的生命周期,如初始化方法和销毁方法。使用`@PostConstruct`和`@PreDestroy`注解来指定这些方法。 ```java @Service public class MyService { @PostConstruct public void init() { // ...
1. **XML配置**:传统的Spring配置通常使用XML文件,如`beans.xml`,其中包含了Bean的定义,包括类名、初始化方法、属性等。例如: ```xml <bean id="exampleBean" class="com.example.ExampleClass"> ...
3. **初始化回调**:在属性注入完成后,Spring会调用Bean的初始化方法。如果在Bean定义中配置了`init-method`,那么这个方法会被执行。此外,实现`InitializingBean`接口的Bean也会自动调用`afterPropertiesSet()`...
初始化回调是指在Bean实例化后、开始使用前执行的方法,可以通过`init-method`属性指定。销毁回调则是在Bean不再使用、即将被销毁时调用的方法,可通过实现DisposableBean接口或`destroy-method`属性设置。 此外,...
你可以为bean定义初始化方法和销毁方法,容器会在适当的时候调用。此外,还可以通过实现InitializingBean和DisposableBean接口,或者使用`@PostConstruct`和`@PreDestroy`注解来定义生命周期行为。 **自动装配...
在 Spring 中,可以使用 `init-method` 和 `destroy-method` 属性来指定 Bean 的初始化和销毁方法。 Bean 是 Spring 框架中的核心组件,理解 Bean 的概念、配置、实例化和生命周期是使用 Spring 框架的基础。
该接口包含两个方法:`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`,这两个方法会在Bean初始化的相应阶段被调用。 总的来说,Spring Bean的生命周期包括实例化、初始化、使用和销毁等...
当我们需要在bean初始化后执行特定的代码时,可以使用`@PostConstruct`注解。这个注解标记的方法会在bean实例化并且所有依赖注入完成后调用。例如: ```java @Component public class AppConfig { @...
9. **Bean后处理器(Bean Post Processor)**: Bean后处理器允许在初始化Bean之后和销毁Bean之前执行自定义逻辑。通过实现`BeanPostProcessor`接口,我们可以自定义Bean的初始化和销毁行为。 10. **Resource注入**:...