自动更新对象

时间:2017-04-04 01:43:46

标签: spring spring-boot java-8 autowired

我有一个场景,我正在使用的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;
}

我在那个班级自动装配工作室。现在每当我运行它时,我都会将从属性文件中填充的字段视为null。我可以看到原因,也就是说,new对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>

1 个答案:

答案 0 :(得分:1)

[编辑:此处显示的完整代码示例也位于github]

试试这个:

//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 + '\'' +
                '}';
    }
}

我们在这里做的是允许Spring控制Studio类的生命周期。您不需要自己创建新的Studio。 Spring在启动时会这样做。由于它也是@ConfigurationProperties类,它还将填充Spring Externalized Configuration中的值。注意:您还需要公共getter和setter,以便Spring可以为您填充值。

FullStudio不是Spring托管类。您可以使用Studio和任何其他API创建自己的FullStudio

这是一个没有配置Java Config @Configuration但是由xml配置管理的类:

public class StudioReader {

    private Studio wiredstudio;

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

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

我们使用这个mycontext.xml文件来创建这个bean,引用wiredstudio。这里的Spring连接的Studio来自我们配置了JavaConfig的Studio实例。 ref的{​​{1}}属性是Spring在将studio类实例化为我们的spring应用程序上下文时根据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配置更麻烦,但是可以做到。

这是一个测试类,展示了如何在使用Spring Java Config和XML配置创建的类中使用Studio类:

@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个文件:

@SpringBootApplication
@ImportResource("classpath:mycontext.xml")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

和我们的application.properties文件:

studio.areacode=303