需求:工具类里引用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

@PostConstruct - 静态方法调用IOC容器Bean对象的更多相关文章

  1. spring深入学习(二)-----bean的生命周期、IOC容器bean装配

    bean的生命周期 1.实例化Bean对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBea ...

  2. 获取Spring容器Bean对象工具类

    在开发中,总是能碰到用注解注入不了Spring容器里面bean对象的问题.为了解决这个问题,我们需要一个工具类来直接获取Spring容器中的bean.因此就写了这个工具类,在此记录一下,方便后续查阅. ...

  3. 【Spring】Spring之向 IOC 容器注入对象的三种方式

    关于Spring的搭建可参见:浅析Spring框架的搭建.在测试之前还是应该先将环境配置好,将相关Jar包导进来.Spring创建的对象,默认情况下都是单例模式,除非通过scope指定. 向IOC容器 ...

  4. 【sping揭秘】4、某些无法注册到IOC容器的对象如何交给spring托管

    可以实现spring的factoryBean 接口,这样可以加入spring的IOC容器 比如现在有一个类叫MyObject,我们没有这个对象的源码,无法对这个对象进行操作,那么我们如何加入sprin ...

  5. Spring IOC的Bean对象

    ---恢复内容开始--- 在Spring IOC模块中Bean是非常重要的.在这里我想给大家讲讲关于Bean对象实例化的三种注入方式: 首先,我先讲一下关于Bean对象属性值的两种注入方式:set注入 ...

  6. IoC容器-Bean管理(bean作用域)

    IoC操作Bean管理(bean作用域) 1,在Spring里面,设置创建bean实例是单实例还是多实例 2,在Spring里面,默认情况下,bean是单实例对象 3,如何设置单实例还是多实例 (1) ...

  7. IoC容器-Bean管理注解方式(创建对象)

    IoC操作Bean管理(基于注解方式) 1,什么是注解 (1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...) (2)使用注解,注解作用在类上面,方法上面,属性上面 ( ...

  8. IoC容器-Bean管理XML方式(创建对象和set注入属性,有参构造注入属性)

    Ioc操作Bean管理 1,什么是Bean管理 (0)Bean管理指的是两个操作 (1)Spring创建对象 (2)Spring注入属性 2,Bean管理操作有两种方式 (1)基于xml配置文件方式实 ...

  9. IoC容器-Bean管理XML方式(引入外部属性文件)

    IoC操作Bean管理(引入外部属性文件) 1,直接配置数据库信息 (1)配置德鲁伊连接池 (2)引入德鲁伊连接池依赖jar包 2,通过引入外部属性文件配置数据库连接池 (1)创建外部属性文件,pro ...

随机推荐

  1. select同时获取value和label的值

    Element ui 框架型 <el-select v-model="sketchID" autocomplete="off" @@change=&quo ...

  2. [洛谷P1144][题解]最短路计数

    这道题可以用各种算法踩掉,我选择的是SPFA. 因为题目要求计数,所以我们开一个ans数组表示数量. 分两种情况讨论: 一:dis_v>dis_u+1 最短路被更新了,可以直接ans_v=ans ...

  3. 在浏览器地址栏输入www.baidu.com到打开百度首页这期间到底发生了什么?

    刚才无意间看到这么一个面试题,觉得有点意思,我想从五层网络模型的角度说说我的看法. 1.首先通过DNS域名系统向域名服务器发送域名解析请求来得到百度的IP地址39.156.69.79:2.系统通过AR ...

  4. asp开发类型判段

    Asp的东西有许多,asp的类型便是其中之一,如同Asp的数据类型只需一个那便是"variant ". 它是一种特别的数据类型可以依据它的运用标明许多不同品种的信息(cnhfjj) ...

  5. 【洛谷5794】[THUSC2015] 解密运算(模拟)

    点此看题面 大致题意: 对于一个字符串,我们在其末尾添加一个'.',将字符串视作一个环,则可以从\(n+1\)个位置断开得到\(n+1\)个新串.现将这\(n+1\)个新串按字典序排序('.'的字典序 ...

  6. 如何开启php错误日志

    nginx与apache不一样,在apache中可以直接指定php的错误日志,那样在php执行中的错误信息就直接输入到php的错误日志中,可以方便查询. 在nginx中事情就变成了这样:nginx只对 ...

  7. Idea中新建yml不显示叶子形状的原因

    IntelliJ IDEA 2019.2.4 x64 (版本),不显示叶子形状,导致写配置无法自动提示(自动提示请安装插件)Spring Assistant 先看一下Editor--->File ...

  8. ASP.NET Repeater与Button 以及viewState 和 hyperLink

    例如Repeater重复项 我们要在一个表里作删除以及修改 我们可以在Repeater中添加button控件前台代码:button有属性commandName 以及commandArgument 我们 ...

  9. PAT 1008 Elevator 数学

    The highest building in our city has only one elevator. A request list is made up with N positive nu ...

  10. Redis在Window下的安装部署

    一.下载 由于redis官方不支持windows,所以需要在github上下载window的版本:下载地址.redis约定版次版本号(即第一个小数点后的数字)为偶数的版本是稳定版本(如2.8,3.0) ...