跳转至

Spring 静态方法调用注入的类

约 184 个字 34 行代码 2 张图片 预计阅读时间 1 分钟

情景

有一个工具类 AreaUtil,其中一个方法 getArea 需要读取数据库。你希望它能够在外面直接以 AreaUtil.getArea() 的形式使用,故要写成静态方法。你希望能够写成这样:

@Component
public class AreaUtil {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public static Optional<AreaInfo> getArea(@NotNull String areaCode) {
        // 读取数据库内容
        jdbcTemplate.queryForObject(...);
        // ...
    }

但此时,IDE 会提示“无法从 static 上下文引用非 static 字段 'jdbcTemplate'”,同时给修复建议:将 jdbcTemplate 设为 static。另外一个选项是将 getArea 设为非静态,但显然不符合你的预期。

IDE 报错
IDE 报错

你要是真的这么做了:

@Component
public class AreaUtil {
    @Autowired
    private static JdbcTemplate jdbcTemplate;

    public static Optional<AreaInfo> getArea(@NotNull String areaCode) {
        // 读取数据库内容
        jdbcTemplate.queryForObject(...);
        // ...
    }

还会报错:“不自动装配 static 成员”。

JdbcTemplate 设为 static 后 IDE 报错
JdbcTemplate 设为 static 后 IDE 报错

解决方法

另外写一个静态的变量,通过 @PostConstruct 变相注入。

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static JdbcTemplate staticJdbcTemplate;

    @PostConstruct
    public void init() {
        staticJdbcTemplate = jdbcTemplate;
    }

    public static Optional<AreaInfo> getArea(@NotNull String areaCode) {
        staticJdbcTemplate.queryForObject();
        // ...
    }

但是这种方法只能在 Spring 框架内部使用。