假设我们的 Spring Boot 有一个 Service
类:
package com.awaimai.service;
import org.springframework.stereotype.Service;
@Service
public class PostService {
public void print(String text) {
System.out.println(text);
}
}
以及一个Lang
枚举类,它会引用 PostService
里面的 print
方法,如下:
package com.awaimai.enumeration;
import org.springframework.beans.factory.annotation.Autowired;
public enum Lang {
CHINESE("这是中文"),
ENGLISH("This is English"),
ARABIC("هذا عربي");
private final String text;
@Autowired
private PostService postService;
Lang(String text) {
this.text = text;
}
public void printText() {
postService.print(text);
}
}
这样写运行的时候会报NullPointerException
错误,因为 @Autowired
只能用在有效 Spring Bean 里面,包括Bean
、Service
、Component
等,而 enum
却不是 Bean,所以 Service 对象不会自动注入进来。
解决办法就是:增加一个内部类,让它在 Spring Boot 启动的时候就往枚举中注入。
package com.awaimai.enumeration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.EnumSet;
public enum Lang {
CHINESE("这是中文"),
ENGLISH("This is English"),
ARABIC("هذا عربي");
private final String text;
private PostService postService;
Lang(String text) {
this.text = text;
}
public void printText() {
postService.print(text);
}
public void setPostService(PostService postService) {
this.postService = postService;
}
@Component
public static class SetPostService {
// 因为这个类是个 Component,所以 Spring Boot 启动的时候会自动注入依赖
@Autowired
private PostService postService;
@PostConstruct
public void setPostService() {
for (Lang lang: EnumSet.allOf(Lang.class)) {
lang.setPostService(postService);
}
}
}
}
下面是测试代码:
package com.awaimai.enumeration;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import static com.awaimai.enumeration.Lang.*;
@SpringBootTest
class LangTest {
@Test
void printText() {
CHINESE.printText();
ENGLISH.printText();
ARABIC.printText();
}
}
打印结果:
这是中文
This is English
هذا عربي
参考资料: