• @PostConstruct


    需求:工具类里引用IOC容器中的Bean,强迫症患者在调用工具类时喜欢用静态方法的方式而非注入的方式去调用,但是spring 不支持注解注入静态成员变量。

    • 静态变量/类变量不是对象的属性,而是一个类的属性,spring是基于对象层面的依赖注入。静态变量不属于对象,只属于类,也就是说在类被加载字节码的时候变量已经初始化了,也就是给该变量分配内存了,导致spring忽略静态变量。

     举个栗子:

    @Component
    public class MessageUtil {
    
        @Resource
        private static MerchantService merchantService;
    
        public static void getMerchant1(Long id) {
            System.out.println(merchantService.getMerchantByMchId(id));
        }
    }

      调用

    注入方式调用工具类
    @Resource
    private MessageUtil messageUtil;
    public void ttt1() {
        messageUtil.getMerchant1(2L);
    }
    
    静态方法调用工具类
    public void ttt() {
        MessageUtil.getMerchant(2L);
    }

    可以将对象托管给spring管理。

    • 执行过程如下:①在IOC容器初始化的时候创建实例对象 ②执行完构造函数 ③执行注解@Resource ④执行PostConstruct注解。
    • 这里解释为什么不能在构造函数中但可以用PostConstruct借用注解注入的对象赋值静态属性。因为构造函数执行的时候,注解中的对象还未执行,为null;而PostConstruct是在注解注入对象之后执行

    利用@PostConstruct注解可以解决该问题

    代码如下 - 2种写法。原理一致。

    @Component
    public class MessageUtil {
    
        @Resource
        private MerchantService merchantService;
    
        private static MerchantService merchantServiceStatic;
    
    
        /**
         * 需求是 : 要在静态方法里面调用IOC容器的bean对象
         * PostConstruct 在构造函数执行之后执行。
         * 可以方便的把注入的bean对象给到静态属性
         */
        @PostConstruct
        public void postConstruct() {
            merchantServiceStatic = this.merchantService;
        }
    
        public static void getMerchant(Long id) {
            System.out.println(merchantServiceStatic.getMerchantByMchId(id));
        }
    
    }
    @Component
    public class MessageUtil {
    
        @Resource
        private MerchantService merchantService;
    
        private static MessageUtil messageUtil;
    
    
        /**
         * 需求是 : 要在静态方法里面调用IOC容器的bean对象
         * PostConstruct 在构造函数执行之后执行。
         * 可以方便的把注入的bean对象给到静态属性
         */
        @PostConstruct
        public void postConstruct() {
            messageUtil = this;
        }
    
        public static void getMerchant(Long id) {
            System.out.println(messageUtil.merchantService.getMerchantByMchId(id));
        }
    
    }

    如果工具类需要注入的对象较多,推荐第二种。这样代码比较少。

    如果需要注入的对象只有一个,推荐第一种,语义比较清晰

    @PostConstruct注解原理参考 https://www.jianshu.com/p/98cf7d8b9ec3

  • 相关阅读:
    Mysq数据库备份(win)
    Mysql保存中文乱码问题
    MySql常用操作
    win下 mysql远程连接设置
    windows下redis的使用
    栈和队列
    ffmpeg 常用命令
    nginx https配置模板
    openssl 、nginx生成配置自签名证书
    https、公钥,私钥,数字证书
  • 原文地址:https://www.cnblogs.com/nightOfStreet/p/11896397.html
Copyright © 2020-2023  润新知