Java spring annotation @PostConstruct practical explanation

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

  1. 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;
  2. @PostConstruct can load some cached data before Servlet initialization , such as: warming up data dictionary, reading properties configuration file;

Guess you like

Origin blog.csdn.net/weixin_44259720/article/details/130385797