静态方法中调用@Autowired
2022-01-26 20:52 话猫 阅读(2010) 评论(0) 编辑 收藏 举报一、背景
1.今天写代码发现有一个使用@Component注解的util类,类中的方法都是static静态修饰的,但是我要修改其中一个静态方法,在静态方法中我要调用一个service类,代码如下
修改前:
1 2 3 4 5 6 7 8 9 10 | @Component @Slf4j public class TestUtil { private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test" ; public static List<Integer> get() { return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer. class , ImmutableList.of( 2 , 5 , 7 , 14 , 16 )); } } |
修改后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Component @Slf4j public class TestUtil { private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test" ; private static final String SWITCH = "switch" ; @Autowired private static JobNeedCarrierQuery jobNeedCarrierQuery; public static List<Integer> get() { if (Lion.getBooleanValue(SWITCH)) { return jobNeedCarrierQuery.doQuery(); } else { return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer. class , ImmutableList.of( 2 , 5 , 7 , 14 , 16 )); } } } |
二、问题
当执行修改后的代码后,发现报了空指针异常,debug发现jobNeedCarrierQuery没有被注入对象,调用doQuery方法是报NPE
三、原因
在 Java 中,针对 static 静态成员,我们有一些最基本的常识:静态变量(成员)它是属于类的,而非属于实例对象的属性;同样的静态方法也是属于类的,普通方法(实例方法)才属于对象。而 Spring 容器管理的都是实例对象,包括它的@Autowired
依赖注入的均是容器内的对象实例,所以对于 static 成员是不能直接使用@Autowired
注入的。这很容易理解:类成员的初始化较早,并不需要依赖实例的创建,所以这个时候 Spring 容器可能都还没“出生”,谈何依赖注入呢?
四、解决方案
2.@PostConstruct方式实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | @Component ( 1 ) @Slf4j public class TestUtil { private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test" ; private static final String SWITCH = "switch" ; @Autowired . ( 2 ) private JobNeedCarrierQuery jobNeedCarrierQuery; private static TestUtil testUtil; ( 3 ) @PostConstruct ( 4 ) public void init(){ testUtil = this ; testUtil.jobNeedCarrierQuery = this .jobNeedCarrierQuery; } public static List<Integer> get() { if (Lion.getBooleanValue(SWITCH)) { return testUtil.jobNeedCarrierQuery.doQuery(BusinessLineEnum.SPOCK_BIKE.getCode()); ( 5 ) } else { return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer. class , ImmutableList.of( 2 , 5 , 7 , 14 , 16 )); } } } |
3.set方法上添加@Autowired注解,类定义上添加@Component注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Component public class TestUtil { private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test" ; private static final String SWITCH = "switch" ; private static JobNeedCarrierQuery jobNeedCarrierQuery; @Autowired <br> public void setDatastore(JobNeedCarrierQuery jobNeedCarrierQuery) {<em> TestUtil.</em>jobNeedCarrierQuery<em>=</em>jobNeedCarrierQuery<em id= "__mceDel" >;<br> }</em><br> public static List<Integer> get() { if (Lion.getBooleanValue(SWITCH)) { return jobNeedCarrierQuery.doQuery(); } else { return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer. class , ImmutableList.of( 2 , 5 , 7 , 14 , 16 )); } }} |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架