SpringBoot in several ways to load the resource initialization

 

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

  From the result, we only have one interface to implement any of these two will be able to complete our resource initialization tasks, you can see that they are loaded before the container is fully started. It is the difference between the two: run the former method parameters are String ... args, directly into the string, the latter parameter is ApplicationArguments, the parameters of the package. The function is the same. Meanwhile annotations can also be used to implement the order @Order resource loading, the smaller the value, the higher the priority. Examples are as follows:

@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, implement the interface can receive ApplicationListener monitor 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("系统初始化结束..........."); } } }

Guess you like

Origin www.cnblogs.com/cnndevelop/p/12064645.html