Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用现有的单例对象进行自动关联注入_Java_Spring_Annotations_Singleton - Fatal编程技术网

Java 使用现有的单例对象进行自动关联注入

Java 使用现有的单例对象进行自动关联注入,java,spring,annotations,singleton,Java,Spring,Annotations,Singleton,我们在应用程序中使用单例服务类: public class LevelApprovalServiceImpl extends BaseBusinessServiceImpl implements LevelApprovalService { /** There's one and only one instance of this class */ private static final LevelApprovalServiceImpl INSTANCE = new Leve

我们在应用程序中使用单例服务类:

public class LevelApprovalServiceImpl extends BaseBusinessServiceImpl implements LevelApprovalService {

    /** There's one and only one instance of this class */
    private static final LevelApprovalServiceImpl INSTANCE = new LevelApprovalServiceImpl();

    /**
     * Constructor is private, use getInstance to get
     * an instance of this class
     */
    private LevelApprovalServiceImpl() {
    }

    /**
     * Returns the singleton instance of this class.
     *
     * @return  the singleton instance of this class.
     */
    public static LevelApprovalServiceImpl getInstance() {
        return INSTANCE;
    }
}
我们最近将Spring升级到Spring 5,并开始在控制器中使用@Autowired注释:

@RestController
@RequestMapping("/approvals")
public class ApprovalRestController extends BaseRestController {
    @Autowired
    transient private LevelApprovalService levelApprovalService;  
}
问题在于,由于这个原因,我们的web应用程序目前有两个单例服务实例:我们自己创建的单例和Spring创建的单例。自动布线。我们希望情况不是这样,所有的东西都有一个单例实例


有没有一种方法可以告诉Spring使用singleton的getInstance()方法,同时仍然使用Spring注释将事物连接在一起?并非所有服务都在Spring前端中使用,因此我们需要让Spring使用我们的单例实例,而不是相反,我们不必切换到基于xml的配置或开始使用配置文件。

您可以在一个
@configuration
类中定义
@Bean
方法

@Configuration
public class Configuration {

    @Bean
    public LevelApprovalService getLevelApprovalService() {
        return LevelApprovalServiceImpl.getInstance();
    }

}

这样,Spring将始终使用您创建的实例。

您可以从配置类中创建并将您的单例实例作为bean添加到Spring容器中:

@Configuration
public class MyConfig {

    @Bean
    public LevelApprovalServiceImpl service() {
        return LevelApprovalServiceImpl.getInstance();
    }
}

选择本机singleton创建或Spring创建是正确的,顺便说一句,您的getInstance()不是线程安全的。

因此,如果不维护我们自己的组件索引,就无法做到这一点?@Nzall抱歉,您所说的“组件索引”是什么意思?我的意思是,除了用@Service注释我们的服务之外,这个解决方案还要求我们拥有一个类,在这个类中我们需要维护一个列表(索引),其中包含我们希望以这种方式实例化的所有服务。忘记注释服务很容易被检测到,因为它会破坏应用程序,不将服务bean添加到此配置类不会破坏应用程序,因此很容易忘记。我希望找到一个解决方案,我们不必维持这样一个指数,无论是在单独的类中还是在我们的spring配置XML文件中。@Nzall如果不将
@Bean
添加到
@configuration
中,仍然会中断应用程序,因为spring将无法
@Autowire
实例。@Nzall您很幸运,spring可以调用构造函数,而不管可见性如何(您的构造函数是私有的)。对我来说,维护一个配置类比允许Spring做任何人都不允许做的事情要好。你能再解释一下线程安全性吗?我不太明白这为什么不是线程安全的。这个服务没有任何状态,所以我不确定线程安全性是否重要。这个服务包含的只是服务方法和几个私有常量。此服务在活动时不应更改。@nZ您完全正确,我的错。我将此单例实现与另一个应支持的同步关键字混淆了。