• Spring 启动加载资源到内存


    前言

           在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。我找到了三种方式解决下面的问题。

    1、使用PostConstruct注解

      这种解决方法比较适用于: 在对于接口响应时间要求比较短,而接口中又需要频繁调用数据库查询,或者调用外部系统的情况下,为了加快接口的响应速度,在项目启动时,将通过途径获取的结果初始化到静态变量或者放置到各种缓存中。

    首先静态代码块不行,静态代码块的执行顺序在Spring注解之前,当执行的时候,调用请求的Service还没有注入进来,执行时会报空指针错误。

    在启动时完成一些初始化的操作,而这些初始化的操作,又要依赖于依赖注入的结果,就无法在构造方法中实现了。为此需要使用@PostConstruct在构造方法之后执行,被@PostConstruct注解的方法会依赖完成后被自动调用。

     关于Constructor,Spring注解,@PostConstruct执行顺序:Constructor >Spring注解> @PostConstruct

    @Component
    public class TestUtils {
        
        @Autowired
        ICommonService commonService;
        
        public static List<Rsp> resourceList = new ArrayList<>(); //初始化的全局静态变量
        private static ICommonService reCommonService;
        
        @PostConstruct
        public void Init() {
            //查询所有的
            Req reqBean = new Req();
            reCommonService=commonService;    
         reqBean.setFindType(PROVINCE_CITY_FIND_TYPE.FIND_TYPE_B.toString());//查询所有 城市 Rsp rsp=reCommonService.getPaAreaCityInfo(reqBean); resourceList.add(rsp); } }

    2、使用ApplicationListener

      

           在初始化缓存或者特定任务的注册的场景下,可以使用Spring提供的ApplicationListener来进行操作。

           首先,要实现ApplicationListener接口并实现onApplicationEvent方法。举例(使用SpringBoot)如下:

    public class ApplicationEventListener implements ApplicationListener<ApplicationEvent> {
      @Autowired
      private PubSubService pubSubService;
    
      @Override
      public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
          ApplicationContext applicationContext = ((ContextRefreshedEvent) event).getApplicationContext();
          GlobolParameters.context = applicationContext;
          BaseLogger.info("ContextRefreshed初始化开始...");
          // 设置上下文
        }
        if (event instanceof ApplicationReadyEvent) {
          //启动发布订阅
          pubSubService = GlobolParameters.context.getBean(PubSubService.class);
          // redis subscribe job
          pubSubService.subscribe();
          // redis publish job
          pubSubService.publish();
        }
        if (event instanceof ApplicationFailedEvent) {
          Throwable exception = ((ApplicationFailedEvent) event).getException();
          BaseLogger.error("【ApplicationFailedEvent】Spring IOC init  error ", exception);
        }
      }
    }

      然后实例化ApplicationEventListener类,在Spring Boot中通过一个配置类进行实例化:

    @Configuration
    public class ListenerConfig {
        @Bean
        public ApplicationEventListener applicationEventListener(){
            return new ApplicationEventListener();
        }
    }

      通过上述代码,在SpringListener中做到,启动了发布订阅的服务。

    3、启动类显式调用

      如果对外调用的服务,需要依赖启动后放置在容器中的上下文的情况,则需要手动在启动类中获取相应的Bean,调用初始化的方法进行初始化。

    public class StartIiApplication{
        public static void main(String[] args) {
            ApplicationContext applicationContext = SpringApplication.run(StartIiApplication.class, args);
            BeanUtil.setApplicationContext(applicationContext);    
            //从启动的容器中获取Bean,并调用初始化方法
            TestUtils util=(TestUtils) applicationContext.getBean("testUtils");
            util.Init();
        
        }
    }
  • 相关阅读:
    开源APM应用性能管理工具调研
    Inside ARC — to see the code inserted by the compiler
    报表应用系统中怎样正确使用图表功能
    创建cifs系统案例之“实现将Windows磁盘共享至Linux”
    Eclipse快捷键 10个最有用的快捷键
    如何生成KeyStore
    android中调用系统的发送短信、发送邮件、打电话功能
    android自带theme
    Android 报错:Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
    Android oncreate onupgrade什么时候被调用
  • 原文地址:https://www.cnblogs.com/lkd934/p/9531943.html
Copyright © 2020-2023  润新知