如何使用 Spring 注解将对象注入(inject)到单例类中?
我有一些代码,如下面的代码片段所示,我想将 B 类的对象注入(inject)其中。
public class A {
private B b;
private static A instance;
private A () {
set some timer tasks
...
}
public A getInstance() {
if (instance == null) { instance = new A(); }
return instance;
}
当我在 b 对象上方使用 @Inject 时,出现 NullPointerException。
public final class SessionHolder {
private static SessionHolder instance;
@Inject
@Getter
@Setter
private PdbIdContainer pdbIdContainer;
private Map<UUID, SessionData> sessionMap;
private SessionHolder() {
this.sessionMap = new ConcurrentHashMap<>();
pdbIdContainer.update();
TimerTask timerTask1 = new TimerTask() {
@Override
public void run() {
Date d = new Date();
sessionMap.entrySet().stream().filter(map -> TimeUnit.MILLISECONDS.toMinutes(
d.getTime() - map.getValue().getLastUseTime().getTime()) >= Integer.parseInt(
AppController.getConfig().getSessionInterval())).forEach(map -> sessionMap.remove(map.getKey()));
}
};
TimerTask timerTask2 = new TimerTask() {
@Override
public void run() {
pdbIdContainer.update();
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(timerTask1,
Integer.parseInt(AppController.getConfig().getSessionMapDelay()),
Integer.parseInt(AppController.getConfig().getSessionMapInterval()));
timer.scheduleAtFixedRate(timerTask2,
Integer.parseInt(AppController.getConfig().getPdbIdsSetDelay()),
Integer.parseInt(AppController.getConfig().getPdbIdsSetInterval()));
}
public static SessionHolder getInstance() {
if (instance == null) {
instance = new SessionHolder();
}
return SessionHolder.instance;
}
public static SessionData getSession(UUID id) {
return getInstance().sessionMap.get(id);
}
public static UUID createSession(StructureContainer structure) {
UUID id = UUID.randomUUID();
getInstance().sessionMap.put(id, new SessionData(structure, new Date()));
return id;
}
}
最佳答案
在 Spring 应用程序中,您不需要也不应该创建单例类。当您创建单例 bean 时,Spring 将确保上下文中仅存在此类的单个实例(单例是默认 bean 作用域)。
你的类应该是这样的:
@Component
public class SessionHolder {
private PdbIdContainer pdbIdContainer;
private Map<UUID, SessionData> sessionMap;
@Autowired // you can omit @Autowired if you use Spring 4.3 or higher
SessionHolder(PdbIdContainer pdbIdContainer) {
this.pdbIdContainer = pdbIdContainer;
this.sessionMap = new ConcurrentHashMap<>();
pdbIdContainer.update();
TimerTask timerTask1 = new TimerTask() {
@Override
public void run() {
Date d = new Date();
sessionMap.entrySet().stream().filter(map -> TimeUnit.MILLISECONDS.toMinutes(
d.getTime() - map.getValue().getLastUseTime().getTime()) >= Integer.parseInt(
AppController.getConfig().getSessionInterval())).forEach(map -> sessionMap.remove(map.getKey()));
}
};
TimerTask timerTask2 = new TimerTask() {
@Override
public void run() {
pdbIdContainer.update();
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(timerTask1,
Integer.parseInt(AppController.getConfig().getSessionMapDelay()),
Integer.parseInt(AppController.getConfig().getSessionMapInterval()));
timer.scheduleAtFixedRate(timerTask2,
Integer.parseInt(AppController.getConfig().getPdbIdsSetDelay()),
Integer.parseInt(AppController.getConfig().getPdbIdsSetInterval()));
}
public SessionData getSession(UUID id) {
return sessionMap.get(id);
}
public UUID createSession(StructureContainer structure) {
UUID id = UUID.randomUUID();
sessionMap.put(id, new SessionData(structure, new Date()));
return id;
}
}
关于java - 使用 spring 注解将对象注入(inject)到单例类中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40516171/