簡體   English   中英

使用Spring注釋將對象注入Singleton類

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM