在最近的学习中,发现了一个非常实用的注解 —— @PostConstruct。通过学习了解,逐步发现它能帮助我更轻松的解决不少原本很复杂的问题。
下面,结合实例介绍 @PostConstruct 注解的特性,因为@PreDestroy基本用不到,所以不浪费篇幅啦。
@PostConstruct 是Java5的时候引入的注解,作用在Servlet生命周期上,实现在Bean初始化之前自定义操作。在项目中,@PostConstruct注解主要是在Servlet初始化之前加载一些缓存数据,如:数据字典,读取properties配置文件等。
通常,@PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。
总结一下 @PostConstruct 的使用和特点:
往往我们在项目启动时需要加载某个方法的时候,可以使用@Component和@PostConstruct组合将一个方法完成初始化操作,@PostConstruct 注解的方法会将在依赖注入完成之后被自动调用。
该注解在整个Bean初始化中执行的顺序:@Constructor(构造方法)-> @Autowired(依赖注入)-> @PostConstruct(注解的方法)。
使用此注解时会影响服务启动时间。服务启动时会扫描WEB-INF/classes的所有文件和WEB-INF/lib下的所有jar包。
上面提到过, @PostConstruct 可以在Servlet初始化之前加载一些缓存数据,如:预热数据字典,读取properties配置文件,那案例就模拟这两个场景:
使用Redis进行的数据预热,需要项目启动以后,触发第一次调用才能生成缓存,而利用 @PostConstruct 注解能让预热数据在Bean初始化阶段完成,比Redis更早。
@Slf4j @Configuration public class BeanConfiguration { @Autowired private BusinessService businessService; // 模拟预热的数据 private static String mysql_data; @PostConstruct public void construct(){ log.info("〓〓〓〓〓〓〓〓〓〓 Autowired 加载完成!!"); mysql_data = businessService.demo5(); log.info("〓〓〓〓〓〓〓〓〓〓 mysql_data = " + mysql_data); } }
@Slf4j @Service public class BusinessServiceImpl implements BusinessService { /** * 模拟从数据库查询数据的操作 */ public String demo5() { log.info("〓〓〓〓〓〓〓〓〓〓 demo5:执行!!"); return "mysql data"; } }
@Value 注解修饰的常量不能是静态的,否则会 null,因为 static 的加载在 @Value 之前。如果不是 static 的,就要每次使用都要去加载一次 .properties 文件,有悖我们设置常量类的初衷。
现在,@PostConstruct注解可以帮我们完成预期,因为@PostConstruct的加载是在static之后的,不会出现null的情况,演示一下:
@Slf4j @Component public class GlobalConstent { @Value("${server.port}") private String port; // 模拟静态常量 public static String server_port; @PostConstruct public void construct(){ log.info("〓〓〓〓〓〓〓〓〓〓 Before PostConstruct:" + server_port); server_port = port; log.info("〓〓〓〓〓〓〓〓〓〓 After PostConstruct:" + server_port); } }
@Slf4j @RestController @RequestMapping("/construct") public class PostConstructController { @RequestMapping("/demo") public String demo() { log.info("〓〓〓〓〓〓〓〓〓〓 server_port:" + GlobalConstent.server_port); return "success"; } }
上一篇:vue打包并部署到nginx上