在 Java 的 Spring 框架里,工具类要注入 Bean 存在一定挑战,因为工具类常使用静态方法,而 Spring 的依赖注入主要针对实例对象。不过,可以通过一些方法实现工具类对 Bean 的注入,以下是详细介绍:
1. 把工具类交由 Spring 管理并使用实例方法注入
若工具类的方法无需为静态的,可将工具类变成 Spring Bean,再用 @Autowired
注入所需 Bean。
示例代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
// 使用 @Component 注解将工具类纳入 Spring 容器管理
@Component
public class MyUtils {
@Autowired
private MyService myService;
public void doSomething() {
// 调用注入的 Bean 的方法
myService.someMethod();
}
}
import org.springframework.stereotype.Service;
@Service
class MyService {
public void someMethod() {
System.out.println("执行服务方法");
}
}
2. 借助静态变量和初始化方法注入
当工具类需要使用静态方法时,可采用静态变量和初始化方法达成注入。
示例代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
// 使用 @Component 注解将工具类纳入 Spring 容器管理
@Component
public class MyStaticUtils {
private static MyService staticMyService;
@Autowired
private MyService myService;
// 使用 @PostConstruct 注解,在 Bean 初始化后执行该方法
@PostConstruct
public void init() {
staticMyService = myService;
}
public static void doSomething() {
// 调用注入的 Bean 的方法
staticMyService.someMethod();
}
}
import org.springframework.stereotype.Service;
@Service
class MyService {
public void someMethod() {
System.out.println("执行服务方法");
}
}
3. 手动从 ApplicationContext
获取 Bean
在特殊情形下,可手动从 ApplicationContext
获取 Bean。
示例代码
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
// 实现 ApplicationContextAware 接口,以获取 ApplicationContext
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}
public class MyManualUtils {
public static void doSomething() {
// 手动从 ApplicationContext 获取 Bean
MyService myService = SpringContextUtil.getBean(MyService.class);
myService.someMethod();
}
}
import org.springframework.stereotype.Service;
@Service
class MyService {
public void someMethod() {
System.out.println("执行服务方法");
}
}
注意事项
- 组件扫描:要保证工具类所在的包在 Spring 的组件扫描范围内,不然 Spring 无法发现并管理该类。
- 线程安全:若工具类使用静态变量存储注入的 Bean,要留意多线程环境下的线程安全问题。