【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 还是啥的,后补吧。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南