静态类中使用Spring自动注入的Bean

很多场景下,某些工具类的功能是作为 静态工具 提供的,尤其是在跨层次调用(比如,不仅仅是从 Controller 层,也可能是 Service 层或者其他地方)时,静态方法是非常方便的。不过,静态方法本身并不适合直接与 Spring 的依赖注入机制结合,这主要是因为静态方法和实例化对象是两个完全不同的概念。依赖注入本质上是实例化的工作,而静态方法不依赖实例,但即便如此,仍然有方法可以解决这个问题:

1. 使用 Spring 上下文获取 Bean

在静态方法中,直接访问 Spring 管理的 Bean 是一个比较常见的做法。可以通过 Spring 上下文 (ApplicationContext) 动态地获取到 Bean,而不需要显式地依赖注入。

解决方案:

使用 ApplicationContext 来获取所需的 Bean,这样你就可以在静态方法中使用 Spring 管理的实例。

示例代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class AccessLogUtil {

    private static ApplicationContext context;

    @Autowired
    public void setApplicationContext(ApplicationContext context) {
        AccessLogUtil.context = context; // Spring 在启动时自动注入 ApplicationContext
    }

    public static R updateAccessLog(String token, String lastTime) {
        // 获取 AccessLogService Bean
        AccessLogService accessLogService = context.getBean(AccessLogService.class);
        
        AccessLogDomain accessLogDomain = new AccessLogDomain();
        accessLogDomain.setToken(token);
        accessLogDomain.setLastAccessTime(lastTime);
        
        accessLogService.updateAccessLog(accessLogDomain);
        return R.ok();
    }
}
解释:
  • ApplicationContext 是 Spring 容器的核心接口,它管理着所有的 Bean。
  • 通过在 AccessLogUtil 类中注入 ApplicationContext(通过 @Autowired),我们可以在静态方法中使用 context.getBean(AccessLogService.class) 来获取到 AccessLogService 的实例。
  • 这种方式让你能够在静态方法中访问 Spring 管理的 Bean,同时避免了直接依赖 Spring 注解带来的问题。

2.避免在工具类中使用静态方法

如果可能,考虑尽量避免在工具类中使用静态方法,因为静态方法本身与依赖注入设计理念并不匹配。你可以将 AccessLogUtil 转化为普通的服务类(非静态的),并在需要使用时,通过构造器注入或其他方式来注入依赖。

示例代码(非静态的服务类):

@Component
public class AccessLogUtil {

    private final AccessLogService accessLogService;

    @Autowired
    public AccessLogUtil(AccessLogService accessLogService) {
        this.accessLogService = accessLogService;
    }

    public R updateAccessLog(String token, String lastTime) {
        AccessLogDomain accessLogDomain = new AccessLogDomain();
        accessLogDomain.setToken(token);
        accessLogDomain.setLastAccessTime(lastTime);
        accessLogService.updateAccessLog(accessLogDomain);
        return R.ok();
    }
}

解释:

  • 将 AccessLogUtil 改为普通的组件类,直接通过构造方法注入 AccessLogService。
  • 这种方式更符合 Spring 的设计模式,避免了静态方法的使用,同时保留了依赖注入的优势。
  • 其他类调用:@Autowired
    private AccessLogUtil accessLogUtil;
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容