@PostConstruct

优质博文:IT-BLOG-CN

一、简介

如果需要在生成对象时就完成某些初始化操作,而且这些初始化操作又依赖于依赖注入@Autowired,那么就无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化。@PostConstruct注解的方法将会在依赖注入完成后被自动调用。类初始化调用顺序: Constructor >> @Autowired >> @PostConstruct

特点:
1、只有一个非静态方法能使用此注解;
2、被注解的方法不得有任何参数;
3、被注解的方法返回值必须为void
4、被注解方法不得抛出已检查异常;
5、此方法只会被执行一次;

@PostConstructJava自带的注解,在方法上添加该注解时,Spring容器初始化的时候会执行该方法。从Java EE5规范开始,Servlet中存在两个注解@PostConstruct@PreDestroy影响Servlet生命周期(加载-实例化-初始化-服务-销毁),这两个注解用来修饰非静态的void无参方法;

@PostConstruct@PreDestroy区别:
【1】@PostConstruct用于标记一个方法,在对象创建后立即执行。它通常用于执行一些初始化操作,例如初始化成员变量或建立数据库连接。
【2】@PreDestroy用于标记一个方法,在对象销毁之前执行。它通常用于执行一些清理操作,例如关闭数据库连接或释放资源。

总结来说,@PostConstruct用于在对象创建后执行初始化操作,而@PreDestroy用于在对象销毁前执行清理操作。这两个注解都是由依赖注入框架自动调用的,无需手动调用。

二、代码

@Service
public class UserAutoBookProcess{
    // 使用到了依赖注入对象
	@Autowired
	private ChineseConfig chineseConfig;

    private Map<Integer, String> map = null;
 
	// 初始化方法
	@PostConstruct
	public void init(){
        ImmutableMap.of(1, chineseConfig.getFirst(), 2, chineseConfig.getSecord());
	}
}

三、源码分析

@PostConstruct注解的实现原理是在Spring容器初始化时,会扫描所有标有该注解的方法,并调用它们。如下:@PostConstruct注解是一个标注在方法上的注解,用于标记一个方法是在bean实例化后被调用的方法。它的定义比较简单,没有任何实现代码。

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}

下面我们来看一下Spring容器是如何扫描并调用@PostConstruct注解的方法的:Spring容器在初始化InitDestroyAnnotationBeanPostProcessor这个类的内部postProcessBeforeInitialization方法里对@PostConstruct这个注解进行识别, 然后通过反射, 对这个方法进行了调用。而postProcessBeforeInitialization这个方法的被调是在bean的初始化。

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = this.findLifecycleMetadata(bean.getClass());

    try {
        metadata.invokeInitMethods(bean, beanName);
        return bean;
    } catch (InvocationTargetException var5) {
        throw new BeanCreationException(beanName, "Invocation of init method failed", var5.getTargetException());
    } catch (Throwable var6) {
        throw new BeanCreationException(beanName, "Failed to invoke init method", var6);
    }
}

四、实战引用

【1】Redis工具类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
 
@Component
public class RedisUtil {
 
    private static RedisTemplate<Object, Object> redisTemplates;
 
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
 
    @PostConstruct
    public void initialize() {
        redisTemplates = this.redisTemplate;
    }
 
    /**
     * 添加元素
     *
     * @param key
     * @param value
     */
    public static void set(Object key, Object value) {
 
        if (key == null || value == null) {
            return;
        }
        redisTemplates.opsForValue().set(key, value);
    }
}

你可能感兴趣的:(Spring,java,spring,后端,开发语言,ide)