目录
- 前言:
- 常见业务背景:
前言:
我们在Spring项目中经常会遇到@PostConstruct注解,可能有的伙伴对这个注解很陌生,出现场景如:
首页介绍一下它的用途:@PostConstruct该注解在Java EE5
规范中加入,被用来修饰一个非静态
的void()方法
。被@PostConstruct修饰的方法会在服务器加载Servlet
的时候运行,并且只会被服务器执行一次
。PostConstruct在构造函数之后执行
,init()方法之前执行
。
通常在Spring项目中,该注解的方法在整个Bean初始化中的执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
注意:
- 除了拦截器这个特殊情况以外,其他情况都不允许有参数,否则spring框架会报IllegalStateException;而且返回值要是void,但实际也可以有返回值,至少不会报错,只会忽略
- 方法随便你用什么权限来修饰,public、protected、private都可以,反正功能是由反射来实现
- 方法不可以是static的,但可以是final的
- 文档中说一个类只能有一个方法加此注解,但实际测试中,我在一个类中多个方法加了此注解,并没有报错,而且都执行了,我用的是 Spring Boot 框架。
常见业务背景:
数据预热:在程序启动的过程中需要从数据库中加载数据并缓存到程序的内存中。
在使用@PostConstruct注解以前,我们的做法是容器启动过程中,通过依赖查找的方式获取到mapper,然后从数据库中获取数据并缓存到内存中,实现方式如下:
@Slf4j
public class MainClass {
public static ClassPathXmlApplicationContext context = null;
private static CountDownLatch shutdownLatch = new CountDownLatch(1);
public static void main(String[] args) throws Exception {
// 加载spring上下文
context = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"});
context.start();
// 从数据库获取数据并缓存到内存
// 1.从容器中获取mapper
ItpcsConfigMapper itpcsConfigMapper = (ItpcsConfigMapper) context.getBean("itpcsConfigMapper");
// 2.从数据库中获取数据
List<ItpcsConfig> RuleResultSet = itpcsConfigMapper.selectAll();
// 3.将数据加载到PropertyMap中
RuleResultSet.forEach(itpcsConfig -> PropertyMap.add(itpcsConfig.getName(), itpcsConfig.getValue()));
context.registerShutdownHook();
log.info(LogUtil.marker(), "System already started.");
shutdownLatch.await();
}
}
使用@PostConstruct注解后:
@Slf4j
@Component
public class InitConfigParameter {
@Resource
private ItpcsConfigMapper itpcsConfigMapper;
@PostConstruct
public void init() throws Exception {
// 将数据库中的参数加载到哈希表中
List<ItpcsConfig> RuleResultSet = itpcsConfigMapper.selectAll();
log.info(LogUtil.marker(RuleResultSet), "init propertyMap");
RuleResultSet.forEach(itpcsConfig -> PropertyMap.add(itpcsConfig.getName(), itpcsConfig.getValue()));
}
}
使用@PostConstruct注解修饰的init方法就会在Spring容器的启动时自动的执行