[英]Injecting objects into singleton class with spring annotations
如何使用spring注釋將對象注入單例類?
我在下面的代碼片段中有一些代碼,我想將B類的對象注入其中。
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;
}
}
如果可行的話,我建議使用CDI注釋( javax.inject.Inject
@Inject
),而不是Spring的@Autowired
。 這樣,如果您需要將另一個人轉移到另一個DI
提供者,則不必依賴Spring。
public class A {
@Inject //or @Autowired - Spring
private B b;
private static A instance;
我認為,如果Spring無法管理對象的生命周期,它不會開箱即用。
啟用此功能的唯一方法是打開編譯時或加載時方面的編織。
您可以完全跳過注入,並獲取應用上下文的實例並從中檢索您的B
實例。
更多詳細信息: 依賴注入到Spring非托管bean中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.