如何使用 spring java 配置在单例 bean 中生成原型对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14880847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Howto generate prototype objects with in a singleton bean using spring java configurations
提问by javaMan
Here is what i have right now which works fine. All it does is a market class which returns an array of items objects:
这是我现在所拥有的,效果很好。它所做的只是一个市场类,它返回一个项目对象数组:
I have class market
我有班级市场
class market {
public ArrayList<Items> createItems(HashMap<String,String> map) {
ArrayList<Items> array = new ArrayList<Items>();
for (Map.Entry<String, String> m : map.entrySet()) {
Item item = new Item();
item.setName(m.key());
item.setValue(m.value());
array.add(item);
}
return array;
}
}
class Item is simple class with getter and setter for name and value
class Item 是一个简单的类,带有用于名称和值的 getter 和 setter
Here is how my config file looks:
这是我的配置文件的外观:
@Configuration
public class MarketConfig {
@Bean
public Market market() {
return new Market();
}
}
How I want to change my code:( REASON: i dont want
我想如何更改我的代码:( 原因:我不想
Item item = new Item();
in then method. I want Spring to inject it into Market)
在 then 方法中。我希望 Spring 将其注入 Market)
class market {
public Item item;
//getters and setters for item
public ArrayList<Items> createItems(HashMap<String,String> map) {
ArrayList<Items> array = new ArrayList<Items>();
for (Map.Entry<String, String> m : map.entrySet()) {
item.setName(m.key());
item.setValue(m.value());
array.add(item);
}
return array;
}
}
@Configuration
public class MarketConfig {
@Bean
@Scope("prototype")
public Item item() {
return new Item();
}
@Bean
public Market market() {
Market bean = new Market();
bean.setItem(item());
}
}
I know that prototype scope will give me new bean each time i call item(); Now i want new bean for each iteration in the for loop of createItems method. How can i tell spring to give me.
我知道每次调用 item() 时,原型作用域都会给我新的 bean;现在我想要在 createItems 方法的 for 循环中为每次迭代创建新的 bean。我怎么能告诉春天给我。
One way i know is Do
我知道的一种方法是做
applicationContext context = new AnnotationConfigApplicationContext();
context.getBean(Item.class);
But is there any other way to get my work done. Thanks
但是有没有其他方法可以完成我的工作。谢谢
回答by danny.lesnik
Yes, you can create prototype method on demand using look-up method
是的,您可以使用查找方法按需创建原型方法
public abstract class ItemFactory {
public abstract Item createItem();
}
now in applicationContext.xml just put the following:
现在在 applicationContext.xml 中只需输入以下内容:
<bean id="item" class="x.y.z.Item" scope="prototype" lazy-init="true"/>
and configure factory:
并配置工厂:
<bean id="itemFactory" class="x.y.z.ItemFactory">
<lookup-method name="createItem" bean="item"/>
</bean>
Now all that you need to do in order to use it is Autowire it inside any bean:
现在为了使用它你需要做的就是在任何 bean 中自动装配它:
and call yout look-up method:
并调用您的查找方法:
@Service
public class MyService{
@Autowired
ItemFactory itemFactory;
public someMethod(){
Item item = itemFactrory.createItem();
}
}
each time you call createItem()
you will receive the reference to newly created instance of Item class.
每次调用时,createItem()
您都会收到对新创建的 Item 类实例的引用。
P.S:I see that you are using @Configuration
instead of xml you need check if look-up method can be configured inside configuration bean.
PS:我看到您使用的@Configuration
是 xml 而不是您需要检查是否可以在配置 bean 中配置查找方法。
Hope it helps.
希望能帮助到你。
Update:The trick is simple:
更新:诀窍很简单:
@Configuration
public class BeanConfig {
@Bean
@Scope(value="prototype")
public Item item(){
return new Item();
}
@Bean
public ItemManager itemManager(){
return new ItemManager() {
@Override
public Item createItem() {
return item();
}
};
}
}
回答by Egor Lyashenko
It can be simplified if you are using Java 8
如果您使用的是 Java 8,则可以简化它
@Configuration
public class Config {
@Bean
@Scope(value = "prototype")
public Item item() {
return new Item();
}
@Bean
public Supplier<Item> itemSupplier() {
return this::item;
}
}
And after that you can use this supplier in your Market class to create prototype Item beans.
之后,您可以在 Market 类中使用此供应商来创建原型 Item bean。
@Component
public class Market {
private final Supplier<Item> itemSupplier;
@Autowired
public Market(Supplier<Item> itemSupplier) {
this.itemSupplier = itemSupplier;
}
private Item createItem() {
return itemSupplier.get();
}
}
Quite simple and there is no need in additional factory beans or interfaces.
非常简单,不需要额外的工厂 bean 或接口。