java 设置运行参数上下文_Spring Java Config:如何使用运行时参数创建原型范围的@Bean?...

每个评论已更新

首先,我不确定您为什么对在Spring 3.x中可以正常使用的内容说“这不起作用”。我怀疑您的配置在某处一定有问题。

这有效:

-配置文件:

@Configuration

public class ServiceConfig {

// only here to demo execution order

private int count = 1;

@Bean

@Scope(value = "prototype")

public TransferService myFirstService(String param) {

System.out.println("value of count:" + count++);

return new TransferServiceImpl(aSingletonBean(), param);

}

@Bean

public AccountRepository aSingletonBean() {

System.out.println("value of count:" + count++);

return new InMemoryAccountRepository();

}

}

-要执行的测试文件:

@Test

public void prototypeTest() {

// create the spring container using the ServiceConfig @Configuration class

ApplicationContext ctx = new AnnotationConfigApplicationContext(ServiceConfig.class);

Object singleton = ctx.getBean("aSingletonBean");

System.out.println(singleton.toString());

singleton = ctx.getBean("aSingletonBean");

System.out.println(singleton.toString());

TransferService transferService = ctx.getBean("myFirstService", "simulated Dynamic Parameter One");

System.out.println(transferService.toString());

transferService = ctx.getBean("myFirstService", "simulated Dynamic Parameter Two");

System.out.println(transferService.toString());

}

使用Spring 3.2.8和Java 7,可以得到以下输出:

value of count:1

com.spring3demo.account.repository.InMemoryAccountRepository@4da8692d

com.spring3demo.account.repository.InMemoryAccountRepository@4da8692d

value of count:2

Using name value of: simulated Dynamic Parameter One

com.spring3demo.account.service.TransferServiceImpl@634d6f2c

value of count:3

Using name value of: simulated Dynamic Parameter Two

com.spring3demo.account.service.TransferServiceImpl@70bde4a2

因此,两次请求“ Singleton” Bean。但是,正如我们期望的那样,Spring仅创建一次。第二次看到它拥有该bean,并仅返回现有对象。构造函数(@Bean方法)不再被调用。与此不同,当从同一个上下文对象两次请求“原型” Bean时,我们看到引用在输出中发生了变化,并且构造函数(@Bean方法)被调用了两次。

因此,问题是如何将单例注入原型。上面的配置类也说明了如何做到这一点!您应该将所有此类引用传递给构造函数。这将使创建的类成为纯POJO,并使所包含的引用对象保持原样不变。因此,转移服务可能类似于:

public class TransferServiceImpl implements TransferService {

private final String name;

private final AccountRepository accountRepository;

public TransferServiceImpl(AccountRepository accountRepository, String name) {

this.name = name;

// system out here is only because this is a dumb test usage

System.out.println("Using name value of: " + this.name);

this.accountRepository = accountRepository;

}

....

}

如果编写单元测试,您会很高兴在没有所有@Autowired的情况下创建了此类。如果确实需要自动装配的组件,请将其保留在Java配置文件的本地。

这将在BeanFactory中调用下面的方法。请在描述中注意这是如何用于您的确切用例的。

/**

* Return an instance, which may be shared or independent, of the specified bean.

*

Allows for specifying explicit constructor arguments / factory method arguments,

* overriding the specified default arguments (if any) in the bean definition.

* @param name the name of the bean to retrieve

* @param args arguments to use if creating a prototype using explicit arguments to a

* static factory method. It is invalid to use a non-null args value in any other case.

* @return an instance of the bean

* @throws NoSuchBeanDefinitionException if there is no such bean definition

* @throws BeanDefinitionStoreException if arguments have been given but

* the affected bean isn't a prototype

* @throws BeansException if the bean could not be created

* @since 2.5

*/

Object getBean(String name, Object... args) throws BeansException;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值