通过源码查看Spring SmartLifecycle 的执行顺序

 

     最新需要用到SmartLifecycle ,写了一个测试类,打印了一下执行顺序如下:

/**
 * 
 * 
 * @author cuiyt
 * @date: 2017年8月31日 上午8:47:54
 */
public class TestSmartLifecycle implements SmartLifecycle {

    private boolean isRunning = false;
    @Override
    public void start() {
        System.out.println("test start-------------------------");
        isRunning = true;
    }

    @Override
    public void stop() {
        System.out.println("test stop-------------------------");
        isRunning = false;
        
    }

    @Override
    public boolean isRunning() {
        System.out.println("test isRunning-------------------------");
        return isRunning;
    }

    @Override
    public int getPhase() {
        System.out.println("test getPhase-------------------------");
        return 0;
    }

    @Override
    public boolean isAutoStartup() {
        System.out.println("test isAutoStartup-------------------------");
        return true;
    }

    @Override
    public void stop(Runnable callback) {
        System.out.println("test callback-------------------------");
        isRunning = false;
    }

}

 

启动顺序


 

停止顺序


 

 

先来看启动顺序为什么执行了两次

test isAutoStartup-------------------------
test getPhase-------------------------

private void startBeans(boolean autoStartupOnly) {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();//获取Lifecycle实现类的bean
        Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
        for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
            Lifecycle bean = entry.getValue();//判断是不是自动启动,这里调用了isAutoStartup
            if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
                int phase = getPhase(bean);//getPhase()方法内部调用了getPhase return (bean instanceof Phased ? ((Phased) bean).getPhase() : 0);
                LifecycleGroup group = phases.get(phase);
                if (group == null) {//如果相同启动顺序的不存在,则新new一个组,并将bean加入到这个组
                    group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                    phases.put(phase, group);
                }
                group.add(entry.getKey(), bean);//如果相同启动顺序的存在,则将bean加入到这个组
}
     }
     if (phases.size() > 0) {

        List<Integer> keys = new ArrayList<Integer>(phases.keySet());
        Collections.sort(keys);
        for (Integer key : keys) {
          phases.get(key).start();//获取所有Lifecyccle并分完组后,则开始真正的执行
      }
    }

 

 

接下来看执行的顺序

test getPhase-------------------------
test isRunning-------------------------
test isAutoStartup-------------------------
test start-------------------------

public void start() {
            if (this.members.isEmpty()) {
                return;
            }
            if (logger.isInfoEnabled()) {
                logger.info("Starting beans in phase " + this.phase);
            }
            Collections.sort(this.members);//这里进行了排序,查看LifecycleGroupMember的源码(见下面代码),发现他实现了Comparable接口,compareTo方法里面再次调用了getPhase()
      for (LifecycleGroupMember member : this.members) { 
    
          if (this.lifecycleBeans.containsKey(member.name)) {
              doStart(
this.lifecycleBeans, member.name, this.autoStartupOnly); //调用doStart()
          }
      } }
    /**
     * Adapts the Comparable interface onto the lifecycle phase model.
     */
    private class LifecycleGroupMember implements Comparable<LifecycleGroupMember> {

        private final String name;

        private final Lifecycle bean;

        LifecycleGroupMember(String name, Lifecycle bean) {
            this.name = name;
            this.bean = bean;
        }

        @Override
        public int compareTo(LifecycleGroupMember other) {
            int thisOrder = getPhase(this.bean);
            int otherOrder = getPhase(other.bean);
            return (thisOrder == otherOrder ? 0 : (thisOrder < otherOrder) ? -1 : 1);
        }
    }

doStart()

/**
     * Start the specified bean as part of the given set of Lifecycle beans,
     * making sure that any beans that it depends on are started first.
     * @param lifecycleBeans Map with bean name as key and Lifecycle instance as value
     * @param beanName the name of the bean to start
     */
    private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
        Lifecycle bean = lifecycleBeans.remove(beanName);
        if (bean != null && !this.equals(bean)) {
            String[] dependenciesForBean = this.beanFactory.getDependenciesForBean(beanName);
            for (String dependency : dependenciesForBean) {
                doStart(lifecycleBeans, dependency, autoStartupOnly);
            }
        //这里判断是否在运行,调用了
isRunning(),isAutoStartup()
      if (!bean.isRunning() && (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) { 
        
if (logger.isDebugEnabled()) {
          logger.debug(
"Starting bean '" + beanName + "' of type [" + bean.getClass() + "]");
        }
        
        try {
          bean.start(); //调用start()
        }
catch (Throwable ex) { throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex); } if (logger.isDebugEnabled()) { logger.debug("Successfully started bean '" + beanName + "'"); } } } }

 

停止顺序

test getPhase-------------------------
2017-08-31 09:06:57.581 INFO 11028 --- [on(2)-127.0.0.1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
test getPhase-------------------------
test isRunning-------------------------
test callback-------------------------

 

同样是先获取实现bean,并分组,调用了两次getPhase()

    private void stopBeans() {
        Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
        Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
        for (Map.Entry<String, Lifecycle> entry : lifecycleBeans.entrySet()) {
            Lifecycle bean = entry.getValue();
            int shutdownOrder = getPhase(bean);//第一次getPhase()
            LifecycleGroup group = phases.get(shutdownOrder);
            if (group == null) {
                group = new LifecycleGroup(shutdownOrder, this.timeoutPerShutdownPhase, lifecycleBeans, false);
                phases.put(shutdownOrder, group);
            }
            group.add(entry.getKey(), bean);
        }
        if (phases.size() > 0) {
            List<Integer> keys = new ArrayList<Integer>(phases.keySet());
            Collections.sort(keys, Collections.reverseOrder());
            for (Integer key : keys) {
                phases.get(key).stop();//开始停止
            }
        }
    }

stop方法

public void stop() {
            if (this.members.isEmpty()) {
                return;
            }
            if (logger.isInfoEnabled()) {
                logger.info("Stopping beans in phase " + this.phase);
            }
            Collections.sort(this.members, Collections.reverseOrder());//排序调用了一次getPhase()
      CountDownLatch latch = new CountDownLatch(this.smartMemberCount); 
      Set
<String> countDownBeanNames = Collections.synchronizedSet(new LinkedHashSet<String>());
    
      for (LifecycleGroupMember member : this.members) {
        
if (this.lifecycleBeans.containsKey(member.name)) {
            doStop(
this.lifecycleBeans, member.name, latch, countDownBeanNames); //调用doStop方法
        }
else if (member.bean instanceof SmartLifecycle) {
  
            // already removed, must have been a dependent latch.countDown(); } }
          
try { latch.await(this.timeout, TimeUnit.MILLISECONDS);
        
            if (latch.getCount() > 0 && !countDownBeanNames.isEmpty() && logger.isWarnEnabled()) {
                   logger.warn(
"Failed to shut down " + countDownBeanNames.size() + " bean" + (countDownBeanNames.size() > 1 ? "s" : "")
                 + " with phase value " + this.phase + " within timeout of " + this.timeout + ": " + countDownBeanNames);
           }
         }
catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } }

doStop()

private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
            final CountDownLatch latch, final Set<String> countDownBeanNames) {

        Lifecycle bean = lifecycleBeans.remove(beanName);
        if (bean != null) {
            String[] dependentBeans = this.beanFactory.getDependentBeans(beanName);
            for (String dependentBean : dependentBeans) {
                doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames);
            }
            try {
                if (bean.isRunning()) {//判断是都还在运行,调用了isRunning()

if (bean instanceof SmartLifecycle) { if (logger.isDebugEnabled()) { logger.debug("Asking bean '" + beanName + "' of type [" + bean.getClass() + "] to stop"); } countDownBeanNames.add(beanName); ((SmartLifecycle) bean).stop(new Runnable() {//调用了stop(Runnable callback) 
@Override
public void run() { latch.countDown(); countDownBeanNames.remove(beanName); if (logger.isDebugEnabled()) { logger.debug("Bean '" + beanName + "' completed its stop procedure"); } } }); } else { if (logger.isDebugEnabled()) { logger.debug("Stopping bean '" + beanName + "' of type [" + bean.getClass() + "]"); } bean.stop(); if (logger.isDebugEnabled()) { logger.debug("Successfully stopped bean '" + beanName + "'"); } } } else if (bean instanceof SmartLifecycle) { // don't wait for beans that aren't running latch.countDown(); } } catch (Throwable ex) { if (logger.isWarnEnabled()) { logger.warn("Failed to stop bean '" + beanName + "'", ex); } } } }

 

posted @ 2017-08-31 09:50  灬雨  阅读(2308)  评论(0编辑  收藏  举报