现在的位置: 首页 > 综合 > 正文

spring源码解读-InitializingBean的实现方法

2012年02月26日 ⁄ 综合 ⁄ 共 1572字 ⁄ 字号 评论关闭

当启动应用的时候spring会自动初始化实现InitializingBean接口的类,并且会自动调用afterPropertiesSet方法。觉得神奇,这种方式到底是如何实现呢?看了一下源码学习其设计原理:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
  implements AutowireCapableBeanFactory {

中的方法invokeInitMethods讲解比较清楚

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
   throws Throwable {

  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 {
    ((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);
   }
  }
 }

 init-method是通过反射机制运行的,因此afterPropertiesSet方法的执行效率比init-method高,但是init-method的优点是消除了对spring的依赖,因此一般情况下,我们建议用init-method方法

抱歉!评论已关闭.