InitializingBean使用

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

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


package org.springframework.beans.factory;

/**
 * 所有由BeanFactory设置的所有属性都需要响应的bean的接口:例如,执行自定义初始化,或者只是检查所有强制属性是否被设置。
 *实现InitializingBean的替代方法是指定一个自定义init方法,例如在XML bean定义中。
 */
public interface InitializingBean {

    /**
     * 在BeanFactory设置了提供的所有bean属性后,由BeanFactory调用。 
     *这个方法允许bean实例在所有的bean属性被设置时才能执行
     */
    void afterPropertiesSet() throws Exception;

}

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

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

这种方式在spring中是怎么实现的呢?
通过查看spring加载bean的源码类(AbstractAutowireCapableBeanFactory)可以看出玄机
AbstractAutowireCapableBeanFactory类中的invokeInitMethods方法讲解的非常清楚,源码如下:

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {
        //首先看该bean是否实现了实现了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>() {
                        @Override
                        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);
            }
        }
    }

观察源码可得出以下结论
summary:

  1. spring为bean提供了两种初始化bean的方式,实现InitializingBean接口而实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用
  2. 实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法相对来说效率要高。但init-method方式消除了对spring的依赖
  3. 若调用afterPropertiesSet方法时产生异常,则也不会再调用init-method指定的方法
目录
相关文章
|
11月前
|
Java Maven
maven打瘦包,且只打入部分想打入的依赖瘦包
maven打瘦包,且只打入部分想打入的依赖瘦包 设计 工程结构分析 环境管理 城市资源 安全工程 工程管理
224 10
|
关系型数据库 MySQL Shell
Mac安装Mysql(图文解说详细版)
Mac安装Mysql(图文解说详细版)
Mac安装Mysql(图文解说详细版)
|
12月前
|
Java
jdk11的HttpClient
本文介绍了JDK 11中新增的HttpClient功能,并通过示例代码展示了如何使用它来发送HTTP请求,包括GET请求和异步请求的处理。
261 2
jdk11的HttpClient
|
11月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
191 0
|
缓存 Java Spring
[AIGC] `InitializingBean`接口 的使用场景
[AIGC] `InitializingBean`接口 的使用场景
269 1
Zp
|
微服务
SpringCloud之@FeignClient()注解的使用
SpringCloud之@FeignClient()注解的使用
Zp
795 0
|
JSON API 数据处理
使用Python调用API接口获取拼多多商品数据:一篇详细说明文章
拼多多是中国著名的电商平台之一,提供了丰富的商品信息和购物服务。为了更好地利用拼多多的数据资源,我们可以使用Python编程语言调用拼多多的API接口,获取商品数据并进行处理和分析。本文将详细介绍如何使用Python完成这一任务,包括API的基本概念、接口调用流程、代码实现和数据处理等方面的内容。
|
弹性计算 NoSQL Redis
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
拆分集合方法Lists.partition的使用
拆分集合方法Lists.partition的使用
462 0
|
NoSQL 安全 Java
redis中list应用场景
redis中list应用场景