【问题标题】:How can Spring instantiate cClasses with private constructors (singleton pattern) and objects from Factories?Spring 如何使用私有构造函数(单例模式)和来自工厂的对象实例化 cClass?
【发布时间】:2014-11-19 11:04:19
【问题描述】:

我正在学习 Spring Core 认证,我对 Spring 如何使用私有构造函数(例如单例模式)实例化类或如何从工厂实例化对象(不是 Spring 上下文)有以下疑问。

例如我有以下单例工厂:

public class AccountServiceSingleton implements AccountService {

    private static AccountServiceSingleton inst = new AccountServiceSingleton();

    private AccountServiceSingleton() { ... }

    public static AccountService getInstance() {
        // ...
        return inst;
    }
}

这是一个单例工厂,因为它构建了一个私有静态对象,该对象由一个私有构造函数构建,而我有一个公共方法 来获取这个对象。

所以我认为问题Spring如何构建这个对象?取决于构造函数是私有的,所以我不能在我的Java配置类中做这样的事情

@Confguration
public class ApplicationConfig{

    @Bean
    public AccountServiceSingleton accountServiceSingleton(){
        return new AccountServiceSingleton();
    }
}

因为我无法访问私有 AccountServiceSingleton() 构造函数。

同时出于同样的原因我不能使用等效的 XML 配置。

我是否了解问题所在或我遗漏了什么?

我认为我遗漏了一些东西,因为在我阅读的文档中,我可以使用以下 2 个解决方案来解决上一个问题:

  1. @Configuration 类中使用@Bean 方法:所以,阅读它,我认为以前的Java 配置类可以工作……但是为什么呢?

  2. XML 配置中的XML factory-method 属性,网上搜索发现应该是这样的,但是如何使用这个来配置之前的AccountServiceSingleton bean in an XML配置?

Tnx

【问题讨论】:

  • 回答名义问题:Reflection。此外,仅仅因为一个类有一个私有构造函数并不意味着它会自动成为一个单例,还有很多其他原因可以让你将构造函数设为私有。
  • 你可能还想看一些答案here

标签: java spring design-patterns singleton factory


【解决方案1】:

真的很简单,你也可以做到:

Constructor cxor = AccountServiceSingleton.class.getDeclaredConstructor();
cxor.setAccessible(true);
return cxor.newInstance();

【讨论】:

【解决方案2】:

我自己找到了答案,仍在阅读文档。我认为这个问题的正确答案是:

如果我想将这个类配置为 Spring bean:

public class AccountServiceSingleton implements AccountService {

    private static AccountServiceSingleton inst = new AccountServiceSingleton();

    private AccountServiceSingleton() { ... }

    public static AccountService getInstance() {
        // ...
        return inst;
    }
}

使用 Java 配置 我只需要在配置类中使用 @Bean 来注释相关 bean 方法。

如果我想使用 XML 配置来配置 bean,我必须使用 factory 方法属性,类似这样:

<bean id=“accountService” class=“com.acme.AccountServiceSingleton” 
      factory-method="getInstance" />

所以它说 getInstance() 方法将被调用以从我的单例工厂获取单例对象

【讨论】:

    【解决方案3】:

    这样怎么样:

    @Confguration
    public class ApplicationConfig{
    
        @Bean
        public AccountServiceSingleton accountServiceSingleton(){
            return AccountServiceSingleton.getInstance();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-05-26
      • 1970-01-01
      • 2016-01-29
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-25
      • 1970-01-01
      相关资源
      最近更新 更多