java - 使用 spring 注解将对象注入(inject)到单例类中

标签 java spring dependency-injection

如何使用 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/

相关文章:

spring - 将 SSL 根证书加载到 TrustManager 失败

asp.net-mvc - 特定可移植区域的ControllerFactory

java - 为什么 hadoop 输出文件 part-r-00000 是空的

java - 如何以编程方式配置 MessageDispatcherServlet

java - 可变长度数组的矩阵的组合

使用@Configuration 或@Component 注释的类的Spring 代理创建

spring - 我应该在这些域类上使用依赖注入(inject)吗?

java - 如果在 xml 中手动创建 bean,Spring 注入(inject)将不起作用

java - 仅当检查整个数组时才使用 Else 语句

Java:无法将 ArrayList<Long> 写入文本文件