Spring中的InitializingBean接口的使用

 更新时间:2018年04月24日 09:08:42   作者:卫旗  
这篇文章主要介绍了Spring中的InitializingBean接口的使用,需要的朋友可以参考下

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

测试,如下:

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");    
  }
}

配置文件

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

Main函数如下

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

测试结果为:

ceshi InitializingBean

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

那么问题来了,在配置bean的时候使用init-method配置也可以为bean配置初始化方法,那这两个哪个会先执行呢,接下来测试一下,修改配置文件,加上init-method:

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

运行程序,得出结果:

ceshi InitializingBean
ceshi init-method

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

那么这种方式在spring中是怎么实现的呢,通过查看Spring加载bean的源码类AbstractAutowiredCapableBeanFactory可以看出其中的奥妙,AbstractAutowiredCapableBeanFactory类中的invokeInitMethods说的非常清楚,如下:

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 InitializingBean的作用

Spring的InitializingBean接口有很好的用处,位于spring beans中,它只提供一个方法afterPropertiesSet(),当你实现了该方法后,spring就会对你提供框架级的支持:当你通过sring容器生产出实现了该接口的类的实例后,它就会调用afterPropertiesSet方法,通过这个方法,你可以检查你的bean是否正确地被初始化了.当然,你也可以用init-method方法.这两种方式可以同时使用,调用的顺序为init-method后调用.

总结

以上所述是小编给大家介绍的Spring中的InitializingBean接口的使用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • Mybatis-plus sql注入及防止sql注入详解

    Mybatis-plus sql注入及防止sql注入详解

    mybatis-plus提供了许多默认单表 CRUD 语句,对于其他SQL情况爱莫能助,下面这篇文章主要给大家介绍了关于Mybatis-plus sql注入及防止sql注入的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • 携程Apollo(阿波罗)安装部署以及java整合实现

    携程Apollo(阿波罗)安装部署以及java整合实现

    这篇文章主要介绍了携程Apollo(阿波罗)安装部署以及java整合实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • SpringMVC使用@PathVariable接收参数过程解析

    SpringMVC使用@PathVariable接收参数过程解析

    这篇文章主要介绍了SpringMVC使用@PathVariable接收参数过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Kafka常用命令之kafka-console-consumer.sh解读

    Kafka常用命令之kafka-console-consumer.sh解读

    这篇文章主要介绍了Kafka常用命令之kafka-console-consumer.sh解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 一个合格JAVA软件工程师应该具备什么

    一个合格JAVA软件工程师应该具备什么

    一个合格JAVA软件工程师应该具备哪些专业技能,面试技巧是什么?本文为大家分享了2016版最新Java软件工程师就业思维图,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • springboot设置加载静态资源的路径(spring.resources.static-locations)

    springboot设置加载静态资源的路径(spring.resources.static-locations)

    这篇文章主要介绍了springboot设置加载静态资源的路径方式(spring.resources.static-locations),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Java和MySQL数据库中关于小数的保存问题详析

    Java和MySQL数据库中关于小数的保存问题详析

    在Java和MySQL中小数的精度可能会受到限制,如float类型的小数只能精确到6-7位,double类型也只能精确到15-16位,这篇文章主要给大家介绍了关于Java和MySQL数据库中关于小数的保存问题,需要的朋友可以参考下
    2024-01-01
  • feignclient https 接口调用报证书错误的解决方案

    feignclient https 接口调用报证书错误的解决方案

    这篇文章主要介绍了feignclient https 接口调用报证书错误的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Spring定时任务实现与配置(二)

    Spring定时任务实现与配置(二)

    这篇文章主要为大家详细介绍了Spring定时任务的实现与配置第二篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • SpringBoot实现RabbitMQ监听消息的四种方式

    SpringBoot实现RabbitMQ监听消息的四种方式

    本文主要介绍了SpringBoot实现RabbitMQ监听消息的四种方式,包括@RabbitListener,MessageListener接口,MessageListenerAdapter适配器,@RabbitHandler这几种,感兴趣的可以了解一下
    2024-05-05

最新评论