foreword
In recent studies, I found a very practical annotation - @PostConstruct. Through learning and understanding, I gradually discovered that it can help me solve many originally complicated problems more easily.
Below, we introduce the features of the @PostConstruct annotation with examples, because @PreDestroy is basically not used, so there is no waste of space.
text
1. Applicable scenarios
@PostConstruct is an annotation introduced in Java5, which acts on the Servlet life cycle and implements custom operations before Bean initialization. In the project, the @PostConstruct annotation is mainly to load some cached data before Servlet initialization , such as: data dictionary, read properties configuration file, etc.
Typically, the @PostConstruct annotation is used on methods that need to be executed after dependency injection is complete, to perform any initialization. The method modified by @PostConstruct will run when the server loads the Servle, and will only be executed once by the server.
Summarize the use and characteristics of @PostConstruct:
- Only one non-static method can use this annotation;
- The annotated method must not have any parameters;
- The return value of the annotated method must be void;
- Annotated methods must not throw checked exceptions;
- This method will only be executed once;
2. Execution order
Often when we need to load a method when the project starts, we can use the combination of @Component and @PostConstruct to complete the initialization operation of a method, and the method annotated with @PostConstruct will be called automatically after the dependency injection is completed.
The order in which the annotation is executed in the entire Bean initialization: @Constructor (construction method) -> @Autowired (dependency injection) -> @PostConstruct (annotated method).
3. Precautions
When using this annotation, it will affect the service startup time. When the service starts, it will scan all files in WEB-INF/classes and all jar packages under WEB-INF/lib.
4. Case Analysis
As mentioned above, @PostConstruct can load some cached data before Servlet initialization, such as: warming up the data dictionary and reading the properties configuration file . The case simulates these two scenarios:
4.1 Data Preheating
Data preheating using Redis requires the first call to generate the cache after the project is started, and using the @PostConstruct annotation allows the preheating data to be completed in the Bean initialization phase earlier than Redis.
- @Component+@PostConstruct completed preheating
@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);
}
}
- BusinessService Demo
@Slf4j
@Service
public class BusinessServiceImpl implements BusinessService {
/**
* 模拟从数据库查询数据的操作
*/
public String demo5() {
log.info("〓〓〓〓〓〓〓〓〓〓 demo5:执行!!");
return "mysql data";
}
}
- Execution effect: As you can see, the data is loaded after dependency injection and before the project is started
4.2 Load configuration file
The constant modified by @Value annotation cannot be static, otherwise it will be null, because static is loaded before @Value. If it is not static, it is necessary to load the .properties file every time it is used, which is contrary to our original intention of setting constant classes.
Now, the @PostConstruct annotation can help us fulfill expectations, because the loading of @PostConstruct is after static, and there will be no null situation. Demonstrate it:
- @Value gets the data, and then assigns a value to the static constant through @PostConstruct
@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);
}
}
- The use process is very friendly, and the method of "class name·" is directly used to access
@Slf4j
@RestController
@RequestMapping("/construct")
public class PostConstructController {
@RequestMapping("/demo")
public String demo() {
log.info("〓〓〓〓〓〓〓〓〓〓 server_port:" + GlobalConstent.server_port);
return "success";
}
}
- Result display: the loading process is before the project is successfully started
Summarize
- The @PostConstruct annotation will affect the service startup time. When the service starts, it will scan all files in WEB-INF/classes and all jar packages under WEB-INF/lib;
- @PostConstruct can load some cached data before Servlet initialization , such as: warming up data dictionary, reading properties configuration file;