2017-04-04 9 views
2

私は、使用しているBeanがプロパティファイルからいくつかのフィールドを取り込み、他は動的に(APIコールから)読み込む必要があるシナリオを考えました。オブジェクトの新規作成の自動化

@Configuration 
@ConfigurationProperties(prefix="studio") 
public class Studio { 

    private String areaCode; // loads from application.properties 

    private String hours; // loads from application.properties 

    private String groupCode; // loads from application.properties 

    private Address address; // loads from a api 

    private String id; // loads from a api 

    public Studio(String id, String city, String subdivision, 
      String addressLine1, String postalCode) { 

     Address address = Address.builder() 
       .street(addressLine1) 
       .city(city) 
       .postalCode(postalCode) 
       .state(subdivision) 
       .build(); 
    this.id = id; 
     this.address = address; 
    } 

} 

今すぐ動的なフィールドを移入する方法は、このようなものです::そのクラスの

private List<Studio> getStudioDataFromApi(ResponseEntity<String> exchange) 
     throws Exception { 

    List<Studio> infoList = $(exchange.getBody()) 
      .xpath("Area[TypeCode=\"CA\"]") 
      .map(
      Area -> new Studio(
       $(Area).child("Id").text(String.class), 
       $(Area).child("Address").child("City").text(String.class), 
       $(Area).child("Address").child("Subdivision").text(String.class), 
       $(Area).child("Address").child("AddressLine1").text(String.class), 
       $(Area).child("Address").child("PostalCode").text(String.class)) 
     ); 
    return infoList; 
} 

I Autowireメーカー は、ここに私のBeanです。これを実行するたびに、プロパティファイルからnullに設定されたフィールドが取得されます。私はその理由を知ることができます。新しい、autowired beanについて何も知らないのです。私の質問はどのように私は両方を使用することができますか?すなわち、新しいものがアップされたときに常に設定からいくつかのフィールドが設定されているBeanを使用する。 コンテキストのxml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/p" 
     xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

     <bean class="org.springframework.batch.core.scope.StepScope" /> 
     <bean id="ItemReader" class="com.sdm.studio.reader.StudioReader" scope="step"> 
      <property name="studio" ref="Studio" /> 
     </bean>  
     <bean id="Studio" class="com.sdm.studio.domain.Studio" />  
</bean> 
+2

@SpringBootApplication @ImportResource("classpath:mycontext.xml") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } 

と私たちのapplication.propertiesファイル2つのクラスに分かれています。 1つのクラスは、構成データを保持するためのConfigurationPropertiesクラスでなければなりません。もう1つは通常のBeanで、スタジオ – Gary

+0

@Garyなどの依存関係をAutowireできる場合は、それらを結合する最も良い方法は何ですか?私はこれらのフィールドを外部のapiに送る必要があります – Yana

答えて

1

私たちがここでやっていることは春のライフサイクルを制御することができている

//This class contains read-only properties, loaded from Spring Externalized Configuration 
@Component 
@ConfigurationProperties(prefix="studio") 
public class Studio { 

    private String areacode; // loads from application.properties 

    //... also add other read-only properties and getters/setters... 

    public String getAreacode() { 
     return areacode; 
    } 

    public Studio setAreacode(String areacode) { 
     this.areacode = areacode; 
     return this; 
    } 

} 

//Just a POJO 
class FullStudio { 
    private String id; 
    private Address address; 

    FullStudio(String id, String city, String areaCode) { 
     this.id = id; 
     this.address = new Address(id, city, areaCode); 
    } 

    @Override 
    public String toString() { 
     return "FullStudio{" + 
       "id='" + id + '\'' + 
       ", address=" + address + 
       '}'; 
    } 
} 
class Address{ 
    String id; 
    String city; 
    String areaCode; 

    public Address(String id, String city, String areaCode) { 
     this.id = id; 
     this.city = city; 
     this.areaCode = areaCode; 
    } 

    @Override 
    public String toString() { 
     return "Address{" + 
       "id='" + id + '\'' + 
       ", city='" + city + '\'' + 
       ", areaCode='" + areaCode + '\'' + 
       '}'; 
    } 
} 

:[編集:完全なコード例ここに示したがgithubにもあります]

これを試してみてくださいStudioクラスの自分で新しいStudioを作成する必要はありません。それが始まると、春はそれを行います。 @ConfigurationPropertiesクラスであるため、Springの値も入力しますExternalized Configuration注:Springが値を入力できるようにパブリック・ゲッターとセッターも必要です。

FullStudioは、Spring管理クラスではありません。 Studioと他のAPIの値を使って独自のFullStudioを作成します。

public class StudioReader { 

    private Studio wiredstudio; 

    public String getMessage(){ 
     return wiredstudio.getAreacode(); 
    } 

    public StudioReader setWiredstudio(Studio studio) { 
     this.wiredstudio = studio; 
     return this; 
    } 
} 

そして、我々はwiredstudioを参照して、このBeanを作成するには、このmycontext.xmlファイルを使用します。ここ

とは、Javaコンフィグ@Configurationで構成されていませんが、代わりにXML設定によって管理されているクラスです。 StudioここでのSpringワイヤは、JavaConfigで設定されたStudioインスタンスからのものです。 studioref属性は、それが私たちの春のアプリケーションコンテキストにそれをインスタンス化したときに春が自動的Studioクラスの名前に基づいて私たちのために選択した名前です。個人的に

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/p" 
     xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <bean id="studioReaderReader" class="com.example.StudioReader" > 
     <property name="wiredstudio" ref="studio" /> 
    </bean> 
</beans> 

、私はそれがその価値よりも多くのトラブルだと思います新しいプロジェクトでSpring BeanのxmlとJava Configurationを結合することができますが、これを行うことができます。ここで

が私たちのスタジオクラスは春のJavaコンフィグやXMLの設定で作成したクラスから使用する方法を示してテストクラスである:このテストを実行するためには

@RunWith(SpringRunner.class) 
@SpringBootTest 
public class StartAppTest { 

    @Autowired private Studio studio; 
    @Autowired private StudioReader studioReader; 

    @Test 
    public void contextok() throws Exception { 
    } 

    @Test 
    public void fullStudio() throws Exception { 
     FullStudio fs = new FullStudio("1", "Denver", studio.getAreacode()); 
     System.out.println("stdio is: " + fs); 
     assertEquals("303", studio.getAreacode()); 
    } 

    @Test 
    public void loadstudioreader() throws Exception { 
     assertEquals("303",studioReader.getMessage()); 
    } 
} 

、あなたは2以上のファイルが必要になります。私はあなたのスタジオCLAを分離することによって開始する

studio.areacode=303 
+0

何とかこれはメインのJavaクラスでは機能しません - 面白い部分は渡されますが、私がクラスを使って(メインのJavaの下で)Studioをオートワイヤリングする場所、クラスはcontext-bean.xmlに定義されています。 – Yana

+0

ああそうです。 Java XML構成とSpring構成を混在させています。私が掲示した例は、JavaConfigだけを使用しています。あなたがただ一つの設定方法を使っているなら、物事はもっと簡単です。 [xmlファイルで定義したBeanにJavaConfig Beanが表示されるように2つの方法を混在させる方法があります](http://memorynotfound.com/mixing-xml-java-config-spring/) – Gary

+0

thx Gary - I 'それを調べて、完全に同意しますが、私のシナリオであなたの例を使用する方法はありますか?つまりXML設定を使用していますか? – Yana

関連する問題