@PostConstruct 注解分析

这篇具有很好参考价值的文章主要介绍了@PostConstruct 注解分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简介

如果需要在生成对象时就完成某些初始化操作,而且这些初始化操作又依赖于依赖注入@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用于标记一个方法,在对象创建后立即执行。它通常用于执行一些初始化操作,例如初始化成员变量或建立数据库连接。

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

【2】@PreDestroy用于标记一个方法,在对象销毁之前执行。它通常用于执行一些清理操作,例如关闭数据库连接或释放资源。

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

@PostConstruct@PreDestroy这两个注解是Java5引入, 已经完全在Java11中删除. 使用需要引入jar

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

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

注意事项: 在使用@PostConstruct注解时,需要注意以下几点:
【1】@PostConstruct注解时会影响服务启动时间,服务启动时会扫描WEB-INF/classes的所有文件和WEB-INF/lib下的所有jar包;
【2】@PostConstruct注解在整个Bean初始化中执行的顺序:@Constructor(构造方法)-> @Autowired(依赖注入)->@PostConstruct(注解的方法);
【3】依赖注入完成后执行,@PostConstruct注解标记的方法将在依赖注入完成后执行。因此,在标记方法的同时,确保所需的依赖已经正确注入到对象中;
【4】方法签名和异常处理,被@PostConstruct注解标记的方法没有特定的方法签名要求,可以是任意访问修饰符、任意返回类型和任意参数列表。然而,建议遵循一致的方法命名和参数命名规范,以提高代码的可读性。此外,被@PostConstruct注解标记的方法应该尽量避免抛出异常。如果抛出异常,容器可能会在对象初始化过程中抛出异常并终止初始化;
【5】与构造函数的区别,@PostConstruct注解标记的方法在对象构造函数执行完成后调用,因此可以看作是构造函数之后的进一步初始化操作。与构造函数不同,@PostConstruct注解的方法可以访问依赖注入的成员变量,并执行更复杂的逻辑;
【6】跨平台兼容性,需要注意的是,@PostConstruct注解是JavaEE标准的一部分,在标准的JavaSE中也被引入。因此,几乎所有的JavaEE容器和一些常见的JavaSE容器都支持@PostConstruct注解。然而,为了确保跨平台兼容性,建议在使用之前进行适当的测试;

二、代码

@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工具类/初始化MQ/数据库连接/基础数据加载等。

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);
    }
}

【2】我们写一个Demo感受下@PostConstruct在服务器加载Servlet的时候运行指定方法,并且只运行一次。

@Component
public class PostConstructDemo {
    @PostConstruct
    public void testPostConstruct() {
        System.out.printf("==========PostConstruct test================");
    }
}

@PostConstruct 注解分析,python,开发语言,java,spring,后端,性能优化,面试

【3】@PostConstruct自定义定时任务的用法

@Controller
public class processTimeoutController {
    @Scheduled(cron = "0 * * * * ?")
    @PostConstruct
    public void processTimeoutMethod() {
        System.out.printf("===job====" + Calendar.getInstance().getTime());
    }
}

【4】配置加载和解析:在应用程序启动时,我们可能需要加载和解析一些配置文件,并将配置信息应用到相应的组件中。可以使用@PostConstruct注解来执行这些配置加载和解析的操作。文章来源地址https://www.toymoban.com/news/detail-803996.html

public class AppConfig {
    private Properties config;

    @PostConstruct
    public void init() {
        // 加载和解析配置文件
        config = // ...
    }
}

到了这里,关于@PostConstruct 注解分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详解Spring Boot中@PostConstruct的使用

    在Java中, @PostConstruct 是一个注解,通常用于标记一个方法,它表示该方法在类实例化之后(通过构造函数创建对象之后)立即执行。 加上 @PostConstruct 注解的方法会在对象的所有依赖项都已经注入完成之后执行。通过使用 @PostConstruct 注解,我们可以确保在对象完全创建和初

    2024年02月10日
    浏览(37)
  • Spring-BeanPostProcessor PostConstruct init InitializingBean 执行顺序

    执行顺序探究 新建一个对象用于测试 新建一个TestBeanPostProcessor 实现 BeanPostProcessor 通过注解的 方式进行测试 得到的结果如下: 总结PostProcessBeforeInitialization - PostConstruct - InitializingBean - PostProcessAfterInitialization 通过Bean.xml的方式 执行结果如下: 总结PostProcessBeforeInitialization - I

    2024年01月20日
    浏览(55)
  • spring管理的bean在静态方法使用技巧——@PostConstruct

            如果我们使用正常的 @Component 注解将一个类交由spring管理,然后在使用的时候用@Resource注入对象,在没有碰到静态方法的时候,是不会出现问题,但是如果出现了静态方法,这样的使用方法就会出现 空指针的异常 ,也就是你@Resource注入的对象是空         一

    2024年02月10日
    浏览(54)
  • Spring Boot 启动注解分析

    虽然我们在日常开发中,Spring Boot 使用非常多,算是目前 Java 开发领域一个标配了,但是小伙伴们仔细想想自己的面试经历,和 Spring Boot 相关的面试题都有哪些?个人感觉应该是比较少的,Spring Boot 本质上还是曾经 SSM 那一套,只是通过各种 starter 简化了配置而已,其他都是

    2024年02月13日
    浏览(42)
  • Spring IOC @Configuration注解分析

    在使用SpringBoot开发时,最常用的注解有@Component、@Service、@Controller、@Configuration等。当类使用这些注解标记时,类会被Spring IOC容器管理,包括创建,填充属性和实例化。 但是Spring容器如何发现并将这些类放到容器进行管理呢? 今天这篇博客主要分析Spring如何处理@Configuratio

    2024年02月08日
    浏览(35)
  • 11Spring IoC注解式开发(下)(负责注入的注解/全注解开发)

    负责注入的注解,常见的包括四个: @Value @Autowired @Qualifier @Resource 当属性的类型是简单类型时,可以使用@Value注解进行注入。 @Value注解可以出现在属性上、setter方法上、以及构造方法的形参上, 方便起见,一般直接作用在属性上. 配置文件开启包扫描: 测试程序: 三种方法都可

    2024年01月16日
    浏览(48)
  • Spring注解开发 -- Spring入门(六)

    为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。 (博客的参考源码可以在我主页的资源里找到,如果在学习的

    2024年02月16日
    浏览(38)
  • Spring基于注解管理bean及全注解开发

    Spring是一款主流的Java EE 轻量级开源框架,目的是用于简化Java企业级引用的开发难度和开发周期。从简单性、可测试性和松耦合度的角度而言,任何Java应用都可以从Spring中受益。Spring框架提供自己提供功能外,还提供整合其他技术和框架的能力。 Spring自诞生以来备受青睐,

    2024年02月14日
    浏览(41)
  • 详细分析Spring中的@Around注解(附Demo)

    此知识点都来源于项目实战,对此进行科普总结,使得之后项目游刃有余 对于Spring的基本知识,推荐阅读: Spring框架从入门到学精(全) java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全) 在Java中, @Around 注解通常与AspectJ框架一起使用,用于定义一个环绕

    2024年04月11日
    浏览(32)
  • Spring 02 -Spring依赖注入+Spring注解开发

    依赖注入:在Spring创建对象的同时,为其属性赋值,称之为依赖注入。 创建对象时,Spring工厂会通过Set方法为对象的属性赋值。 范例:定义一个Bean类型 属性注入 范例:定义一个Bean类型 提供构造方法 构造方法注入 复杂类型指的是:list、set、map、array、properties等类型 定义

    2023年04月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包