由@PostConstruct导致的tomcat启动阻塞

在Spring项目中,通常会在一些组件中做一些初始化的操作,例如初始化一些缓存,初始化加载数据到内存,初始化数据库中的数据,初始化分布式锁等等等等。但是初始化这个操作如果耗时,可能会导致项目启动特别慢,甚至出现web容器启动过程中被阻塞,服务长时间无法访问的情况,下面将举例说明这个问题。

温馨提示:本博客已经发布小程序,可在微信小程序中搜索”百变码农”,手机上也能看!

1、示例代码

配置类BeanConfig:

@Configuration
@ComponentScan(basePackages = "com.wb.spring.propertyvalue")
public class BeanConfig {
   @Bean
   public Person person() {
      return new Person();
   }
}

实体类Person:

public class Person {
   @PostConstruct
   public void initTask() {
      System.out.println("******");
      try {
         Thread.sleep(300000L);
      } catch (Exception e) {
         e.printStackTrace();
      }
      System.out.println("init finished...");
   }
}

测试类:

public class TestMain {
   public static void main(String[] args) {
      ApplicationContext acx = 
        new AnnotationConfigApplicationContext(BeanConfig.class);
      Object person = acx.getBean("person");
      System.out.println(person);
   }
}

运行测试类会发现,打印出”******”之后,然后一直处于阻塞状态,无法继续向下运行。

原因:Spring在初始化bean的时候,会扫描@PostConstruct标注的初始化方法,此时初始化方法比较耗时,阻塞初始化线程。

2、Web应用中使用@PostConstruct注解

(1)现象

如果在@PostConstruct中运行了同步的耗时方法,将会导致tomcat启动线程被阻塞。

(2)原因

Web应用中,Tomcat启动的时候,会扫描类路径下HadlerTypes注解标注的子类或者间接子类,然后执行容器刷新操作,去完成Bean的创建和依赖注入。使用@PostConstruct注解的时候,而在刷新Spring容器的时候,初始化@PostConstruct注解标注的初始化方法,将会导致tomcat用于初始化容器的线程被阻塞,无法继续完成其他初始化操作,而导致阻塞。

(3)解决办法

① 用法上,在@PostConstruct中的初始化应该尽可能简单,例如:初始化分布式锁,初始化jvm缓存,异步启动一些后台线程等;

② 如果需要在初始化时执行一些耗时的操作,可以考虑开启线程,使用异步的方式,此时不会阻塞住初始化容器的线程;

(4)示例代码

上述1中的实例代码中的Person类可以修改为如下:

public class Person {
  @PostConstruct
  public void initTask() {
    System.out.println("******");
    new Thread(()-> {
      try {
        Thread.sleep(300000L);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }).start();
    System.out.println("init finished...");
  }
}

会立刻输出”******”和”init finished…”,不会同步阻塞主线程的执行。

至此,由@PostConstruct注解导致的tomcat启动阻塞问题说明完毕,欢迎转发!关于@PostConstruct的应用可以参考文章Spring常用注解之Bean生命周期相关注解

注意:文章属于原创,如果转发请标注文章来源:个人小站【www.jinnianshizhunian.vip

另外提供一些优秀的Java架构师及IT开发视频,书籍资料。无需注册,无需登录即可下载,免费下载地址:https://www.592xuexi.com