SpringBoot in several ways resource initialization loaded (see this one is enough)

Original difficult, if reproduced, please indicate the source https://www.cnblogs.com/baixianlong/p/11117665.html , thanks to support Ha! ! !

First, the problem

  In the usual course of business module development, we will inevitably need to do some global tasks, cache, threads, etc. initialization work, then how to solve this problem? There are a number of ways, but the specific but also how to choose?

Second, the resource initialization

1, since the initialization of resources do, then you need to know about springboot boot process (generally speaking here at the boot process, detail: https://www.cnblogs.com/dennyzhangdd/p/8028950.html )

spring container starts .png

According to the foregoing analysis, Spring-boot to start the process container can be divided generally into two parts:

  • Performing annotation: bean scan the specified range, the automatic loading configuration class corresponding to loads bean IOC container.
  • The method particularly man SpringAppliocation.run (), through the whole process SpringApplicationEvent (classic spring event-driven model), there are six sub-classes:
    1. ApplicationFailedEvent.class
    2. ApplicationPreparedEvent.class
    3. ApplicationReadyEvent.class
    4. ApplicationStartedEvent.class
    5. ApplicationStartingEvent.class
    6. SpringApplicationEvent.class

2、CommandLineRunner和ApplicationRunner

  由上可知,我们只要实现这两个中的任何一个接口便可以完成我们的资源初始化任务,可以看到它们的加载是在容器完全启动之前。它两的区别是:前者的run方法参数是String...args,直接传入字符串,后者的参数是ApplicationArguments,对参数进行了封装。功能上是一样的。同时也可以使用 @Order注解来实现资源加载的先后顺序,值越小,优先级越高。实例如下:

@Component
@Order(1)
public class MyCommandLineRunner implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("...init resources by implements CommandLineRunner");
    }
}

@Component
@Order(2)
public class MyApplicationRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        System.out.println("...init resources by implements ApplicationRunner");
    }
}

3、@PostConstruct

  在具体Bean的实例化过程中执行,@PostConstruct注解的方法,会在构造方法之后执行,顺序为Constructor > @Autowired > @PostConstruct > 静态方法,所以这个注解就避免了一些需要在构造方法里使用依赖组件的尴尬(与之对应的还有@PreDestroy,在对象消亡之前执行,原理差不多)。使用特点如下:

  • 只有一个非静态方法能使用此注解
  • 被注解的方法不得有任何参数
  • 被注解的方法返回值必须为void
  • 被注解方法不得抛出已检查异常
  • 此方法只会被执行一次

    @Component
    public Class AAA {    
        @Autowired    
        private BBB b;   
    
        public AAA() {        
            System.out.println("此时b还未被注入: b = " + b);    
        }    
        @PostConstruct    
        private void init() {        
            System.out.println("此时b已经被注入: b = " + b);    
        }
    }

4、InitializingBean

  InitializingBean 是 Spring 提供的一个接口,只包含一个方法 afterPropertiesSet()。凡是实现了该接口的类,当其对应的 Bean 交由 Spring 管理后,当其必要的属性全部设置完成后,Spring 会调用该 Bean 的 afterPropertiesSet()。在Bean在实例化的过程中执执行顺序为:Constructor > @PostConstruct > InitializingBean > init-method

public class InitSequenceBean implements InitializingBean {   
    
    public InitSequenceBean() {   
       System.out.println("InitSequenceBean: constructor");   
    }   
      
    @PostConstruct  
    public void postConstruct() {   
       System.out.println("InitSequenceBean: postConstruct");   
    }   
      
    public void initMethod() {   
       System.out.println("InitSequenceBean: init-method");   
    }   
      
    @Override  
    public void afterPropertiesSet() throws Exception {   
       System.out.println("InitSequenceBean: afterPropertiesSet");   
    }   
}

5、ApplicationListener

  ApplicationListener is spring listener, it can be used to monitor events, the typical observer mode. If there is a ApplicationListener Bean container whenever ApplicationContext release ApplicationEvent, ApplicationListener Bean will automatically be triggered. This event mechanism must require the program to display the trigger. There are some built-in which the spring event, upon completion of certain operations will be issued some event action. For example, listen ContextRefreshedEvent event, when all of the bean are initialized and after a successful completion of loading will trigger the event, to achieve ApplicationListener Interface monitor can receive action, then you can write your own logic. The same event can customize, monitor can also be customized, fully processed according to their own business logic. So you can do the initialization load resources!

@Component
public class DataSourceInitListener implements ApplicationListener<ContextRefreshedEvent> {//ContextRefreshedEvent为启动事件
 
    private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceInitListener.class);
 
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private ItemService itemService;
    @Autowired
    private SystemResultService systemResultService;
 
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if(event.getApplicationContext().getParent() == null) {//判断是否执行过,执行过则不再执行
            LOGGER.info("初始化systemConfig数据");
            systemConfigService.initConfig();
            LOGGER.info("初始化返回消息数据");
            systemResultService.initResult();
            LOGGER.info("系统初始化结束...........");
        }
    }
 
}

Third, the summary

  • Some of this resource initialization method say almost, which inevitably some the wrong place, or biased understanding of where we are welcome to put forward!

Personal blog address:

csdn:https://blog.csdn.net/tiantuo6513

cnblogs: https://www.cnblogs.com/baixianlong

segmentfault:https://segmentfault.com/u/baixianlong

github:https://github.com/xianlongbai

Guess you like

Origin www.cnblogs.com/baixianlong/p/11117665.html