6

これが私が今持っているもので、うまく機能します。それが行うのは、アイテムオブジェクトの配列を返すマーケットクラスだけです。

クラスマーケットがあります

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は、名前と値にgetterとsetterを使用する単純なクラスです。

これが私の設定ファイルの外観です:

@Configuration
public class MarketConfig {

    @Bean
    public Market market() {
        return new Market();
    }
}

コードを変更したい方法:(理由:したくない

Item item = new Item(); 

その後の方法で。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());
    }
}

item()を呼び出すたびに、プロトタイプスコープが新しいBeanを提供することを知っています。ここで、createItemsメソッドのforループの反復ごとに新しいBeanが必要です。どうすれば春に私に与えるように言うことができますか。

私が知っている1つの方法はDoです

applicationContext context = new AnnotationConfigApplicationContext();
context.getBean(Item.class);

しかし、私の仕事を成し遂げる他の方法はありますか。ありがとう

4

2 に答える 2

20

はい、ルックアップメソッドを使用してオンデマンドでプロトタイプメソッドを作成できます

public abstract class ItemFactory {

    public abstract Item createItem();

}

これで、applicationContext.xmlに次のように入力します。

<bean id="item" class="x.y.z.Item" scope="prototype" lazy-init="true"/>

ファクトリを構成します。

<bean id="itemFactory" class="x.y.z.ItemFactory">
<lookup-method name="createItem" bean="item"/>
</bean>

これで、それを使用するために必要なのは、任意のBean内でAutowireすることだけです。

そして、youtルックアップメソッドを呼び出します。

@Service 
public class MyService{

   @Autowired
   ItemFactory itemFactory;

   public someMethod(){
      Item item = itemFactrory.createItem();
   } 

}

呼び出すたびcreateItem()に、新しく作成されたItemクラスのインスタンスへの参照を受け取ります。

PS: xmlの代わりに使用しているようですが、@Configuration構成Bean内でルックアップメソッドを構成できるかどうかを確認する必要があります。

それが役に立てば幸い。

更新:トリックは簡単です:

@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();
            }
        };
    }
}
于 2013-02-14T18:02:49.467 に答える
5

Java 8を使用している場合は、簡略化できます。

@Configuration
public class Config {

  @Bean
  @Scope(value = "prototype")
  public Item item() {
      return new Item();
  }

  @Bean
  public Supplier<Item> itemSupplier() {
      return this::item;
  }
}

その後、Marketクラスでこのサプライヤを使用して、プロトタイプのItemBeanを作成できます。

@Component
public class Market {

  private final Supplier<Item> itemSupplier;

  @Autowired
  public Market(Supplier<Item> itemSupplier) {
      this.itemSupplier = itemSupplier;
  }

  private Item createItem() {
      return itemSupplier.get();
  }

}

非常にシンプルで、追加のファクトリBeanやインターフェイスは必要ありません。

于 2016-09-02T12:59:44.587 に答える