前言

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

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(); }
}

Spring 启动加载资源到内存的更多相关文章

  1. spring启动加载过程源码分析

    我们知道启动spring容器两常见的两种方式(其实都是加载spring容器的xml配置文件时启动的): 1.在应用程序下加载 ApplicationContext ctx = new ClassPat ...

  2. as3 Loader 加载资源后内存泄露无法释放的问题。

    本人用Loader加载外部一个swf.之后unloadAndStop,Flash概要分析发现,内存没有被释放. 网上搜了一大堆文章,要么就是加载bitmapdata之后,自己dispose,要么就是加 ...

  3. 解析spring启动加载dubbo过程

    一:简单配置 web.xml <context-param> <param-name>contextConfigLocation</param-name> < ...

  4. tomcat启动加载web项目内存溢出

    通过tomcat命令启动tomcat的web项目时,根据项目大小,有可能会报以下两个错误. 在启动时没有错误,但是在访问时会报错: 1. java.lang.OutOfMemoryError: Jav ...

  5. spring启动加载类,手动加载bean

    方法一: public final class Assembler implements BeanFactoryPostProcessor { private static ConfigurableL ...

  6. Aery的UE4 C++游戏开发之旅(4)加载资源&创建对象

    目录 资源的硬引用 硬指针 FObjectFinder<T> / FClassFinder<T> 资源的软引用 FSoftObjectPaths.FStringAssetRef ...

  7. Spring 启动时加载资源

    Spring加载资源文件目前了解三种, @PostConstruct在Context加载完成之后加载.在创建各个Bean对象之前加载. 实现ApplicationRunner的run方法,Bean加载 ...

  8. Spring boot 国际化自动加载资源文件问题

    Spring boot 国际化自动加载资源文件问题 最近在做基于Spring boot配置的项目.中间遇到一个国际化资源加载的问题,正常来说只要在application.properties文件中定义 ...

  9. spring加载资源文件中classpath*与classpath的区别

    在spring和MyBatis继承的时候,配置mapperLocations.一开始配置是这样的. 需要加载路径为com/thomas/base/mapper和com/thomas/bu/mapper ...

随机推荐

  1. codeforces524E

    题意:n*m的矩阵,给出k个点,Q次询问,问每个矩阵中每个点是否被看管,一个点被看管的定义是那个点所在的行或列有点,n,m<=1e5,k,q<=2e5 sol :发现行和列是独立的,即要么 ...

  2. Vue的学习--遇到的一些问题和解决方法(二)

    1.关于图片路径问题 1.关于图片路径问题 在.vue的html中可以直接使用相对路径,但是从浏览器后台可以看出,最后路径是自行做了替换的.如果需要在js文件中使用,则需要自己使用require进行替 ...

  3. CF1174C Ehab and a Special Coloring Problem(数论)

    做法 与\(x\)互质的数填不同的数,把有向关系表示出来,发现边数是不能承受的 反过来想,成倍数关系填相同的数,把这些数想象成一条链,而这条链开始的数一定是质数,\(\sum\limits_{prim ...

  4. Java学习日记基础(五)——类、对象之this、静态变量(类变量)、静态方法(类方法)、四大特征

    this 赵本山问奥尼尔:“我的爸爸的爸爸是谁?” 奥尼尔:“不知道” 赵本山:“你傻啊,是我爷爷” 奥尼尔回去问科比:“我的爸爸的爸爸是谁?” 科比:“不知道” 奥尼尔:”你傻啊,是赵本山的爷爷“ ...

  5. 简单动态字符串-redis设计与实现

    简单动态字符串 Sds (Simple Dynamic String,简单动态字符串)是 Redis 底层所使用的字符串表示, 几乎所有的 Redis 模块中都用了 sds. 本章将对 sds 的实现 ...

  6. 2018-2019-2 网络对抗技术 20165311 Exp 9 Web安全基础

    2018-2019-2 网络对抗技术 20165311 Exp 9 Web安全基础 基础问题回答 实践过程记录 WebGoat安装 SQL注入攻击 1.命令注入(Command Injection) ...

  7. RK3399 4G模块移远EC20移植调试

    转载请注明出处:https://www.cnblogs.com/lialong1st/p/11266330.html CPU:RK3399 系统:Android 7.1 1.通过串口打印或者adb获取 ...

  8. CSS中的cursor属性

    css中的cursor这个属性是用来设置光标形状的. 这个属性定义了鼠标指针放在一个元素边界范围内时所用的光标的形状. 默认值:auto 继承性:yes 出现版本:css2 JavaScript语法: ...

  9. laravel 查询数据库first()返回的数据转数组

    使用 get_object_vars()可以将他抓转为数组get_object_vars — 返回由对象属性组成的关联数组: 在laravel中其实还可以用 toArray(); json_decod ...

  10. MediaPlayer: BufferQueue has been abandoned 解决方案

    最近在做一个播放器,需要实现一个从小屏切换到全屏的效果,我用的是TextureView + MediaPlayer 的方式去实现,当需要切换成全屏时,我在 TextureView 的 onSurfac ...