背景
做一个工具类时,报NullPointerException异常,debug后发现,注入的service为null。代码如下:
package com.gwall.utils;
public class StringReplaceUtil {
@Resource
private static SystRepository systRepository;
public static String replace(String oldString) {
SqlBuilder builder = new WhereBuilder();
List<Syst> systList = systRepository.findAllByWhere(builder);
return "";
}
}
解决过程
初步分析(静态变量)
因为注入的属性是static静态变量,所以初步断定是因为bean不允许注入到静态变量中。
尝试:
方案一:setter注入(推荐)
package com.gwall.utils;
public class StringReplaceUtil {
private static SystRepository systRepository;
public SystRepository getSystRepository() {
return systRepository;
}
// spring注入不能注入到static属性中,所以用setter注入。放入Service中加入service注解,才能正确注入
@Resource
public void setSystRepository(SystRepository systRepository) {
StringReplaceUtil.systRepository = systRepository;
}
public static String replace(String oldString) {
SqlBuilder builder = new WhereBuilder();
List<Syst> systList = systRepository.findAllByWhere(builder);
return "";
}
}
方案二:再定义一个变量注入
// 网上找到的解决方案,可以参考一下
public class Test {
@Resource
private SystRepository systRepository;
private static SystRepository staticSystRepository;
@PostConstruct
void init() {
staticSystRepository = systRepository;
}
}
结果:
依然报错
第二步分析(spring扫描)
spring是通过组件扫描和自动装配来管理bean的。因为组件扫描需要配置扫描范围,所以要确定类是否在扫描范围内。
尝试:
根据配置把类转移到service扫描位置
package com.gwall.service.impl;
public class StringReplaceUtil {
private static SystRepository systRepository;
public SystRepository getSystRepository() {
return systRepository;
}
// spring注入不能注入到static属性中,所以用setter注入。放入Service中加入service注解,才能正确注入
@Resource
public void setSystRepository(SystRepository systRepository) {
StringReplaceUtil.systRepository = systRepository;
}
public static String replace(String oldString) {
SqlBuilder builder = new WhereBuilder();
List<Syst> systList = systRepository.findAllByWhere(builder);
return "";
}
}
结果:
依然报错
第三步分析(spring组件声明)
类要作为bean被spring发现、管理,首先应该声明为组件类
package com.gwall.service.impl;
@Service
public class StringReplaceUtil {
private static SystRepository systRepository;
public SystRepository getSystRepository() {
return systRepository;
}
// spring注入不能注入到static属性中,所以用setter注入。放入Service中加入service注解,才能正确注入
@Resource
public void setSystRepository(SystRepository systRepository) {
StringReplaceUtil.systRepository = systRepository;
}
public static String replace(String oldString) {
SqlBuilder builder = new WhereBuilder();
List<Syst> systList = systRepository.findAllByWhere(builder);
return "";
}
}
尝试:
加上对应的组件声明注解(@Component@Controller@Service@Repository)
结果:
成功
总结
- 是否添加组件声明注解(@Component@Controller@Service@Repository)
- 是否在扫描范围内
- 是否注入到static变量