【Spring】静态方法(工具类)中调用Spring管理的Bean
背景
在一些业务开发,经常会写一些工具类,但这些工具类时常需要调用到 Spring管理的bean,这些Spring管理的bean 注入,
平常用的都是 @Autowired 注解一个成员变量,
问题就来了:
(1)成员变量(即Spring管理的bean)是非静态的,但工具类都是想写静态方法,静态方法不能引入一个非静态的变量。所以在静态方法里面写不了
(2)如果把成员变量(即Spring管理的bean)写成静态的话,这样的话,静态方法是可以用这个变量了,但是运行的时候,会喜提一个NPE。
比如下面这个例子, signRepository 会 NPE
@Component
public class ScriptExecuteContent {
@Autowired
private static SignRepository signRepository;
public static String checkSign(String certNo, String acctNo, String instCode) {
Sign sign = signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
if (null != sign
&& StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
&& DateUtil.getCurrentDate().before(sign.getExpireTime())) {
return "1";
} else {
return "0";
}
}
}
静态方法怎样引入Spring管理的Bean呢
方法有二(应该不止两种,这里只说两种比较方便点的)
1、 @Autowired 用在构造函数上 (@Resource 也是一样的)
@Component
public class ScriptExecuteContent {
// 成员变量变成 static
private static SignRepository signRepository;
// 构造函数加上 @Autowired
@Autowired
public ScriptExecuteContent(SignRepository signRepository) {
ScriptExecuteContent.signRepository = signRepository;
}
// 静态方法就可以用了
public static String checkSign(String certNo, String acctNo, String instCode) {
Sign sign = signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
if (null != sign
&& StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
&& DateUtil.getCurrentDate().before(sign.getExpireTime())) {
return "1";
} else {
return "0";
}
}
}
2、 使用 @PostConstruct 注解
@Component
public class ScriptExecuteContent {
// 这里定义成员变量
@Autowired
private SignRepository signRepository;
// 要把类也变成静态变量?
private static ScriptExecuteContent scriptExecuteContent;
// 构造方法
@PostConstruct
public void init() {
scriptExecuteContent = this;
scriptExecuteContent.signRepository = this.signRepository;
}
// 静态方法,用的时候是 scriptExecuteContent.signRepository
public static String checkSign(String certNo, String acctNo, String instCode) {
Sign sign = scriptExecuteContent.signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
if (null != sign
&& StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
&& DateUtil.getCurrentDate().before(sign.getExpireTime())) {
return "1";
} else {
return "0";
}
}
}
嗯,通过这两种方式,也基本够用了。
还有另外一些方式,,,,, aware 还是啥的,后补吧。。。