2014-10-09 105 views
0

從Spring XML配置樣式遷移到Spring基於Java的配置(使用@Configuration)我遇到了一個加載資源的問題,在我的例子中是從classpath中。Spring基於Java的配置加載資源(從類路徑)

在XML我也有一顆豆聲明如下:

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
    <property name="schema" value="classpath:/xsd/schema.xsd" /> 
    <property name="contextPath" value="com.company.app.jaxb" /> 
</bean> 

配置這個bean的Java類的樣子:

@Configuration 
public class AppConfig { 

    @Autowired 
    private ApplicationContext applicationContext; 

    @Bean 
    public Marshaller marshaller() { 
     Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 
     marshaller.setSchema(applicationContext.getResource("classpath:/xsd/schema.xsd")); 
     marshaller.setContextPath("com.company.app.jaxb"); 
     return marshaller; 
    } 

這實際上是ApplicationContext因爲負載時拋出NullPointerException @Autowired字段是(還沒有?)自動裝配...

問:什麼是正確的解決方案來加載資源(從c lasspath和/或一般)? Spring文檔中使用ApplicationContext進行了推廣:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#context-introduction

問:爲什麼autowired字段仍爲空?

+0

通常Spring允許基於Java的配置的創建通過 'ApplicationContext context = new AnnotationConfigApplicationContext(springConfig)'其中_springConfig_是對'@ Configuration'註釋配置類的引用,但我從來沒有在配置文件本身TBH中使用它,你也可以嘗試初始化編組器一個'@ PostConstruct'註釋方法在配置 – 2014-10-09 15:33:18

+0

我開始'ApplicationContext'從單元測試使用@RunWith(SpringJUnit4ClassRunner.class)''@ContextConfiguration(classes = {AppConfig.class})'...這是否應用其他一些生命週期? – 2014-10-14 08:18:12

回答

0

對於

marshaller.setSchema(applicationContext.getResource("classpath:/xsd/schema.xsd")); 

,您可以改用

marshaller.setSchema(new ClassPathResource("/xsd/schema.xsd")); 

但我無法重現您的注入ApplicationContext字段爲null

+0

嗯..奇怪。我得到一個在beans jar中的異常:'java.lang.NoClassDefFoundError:org.springframework.beans.FatalBeanException'。我一點也不明白 – 2014-10-14 08:22:08

+0

@MarcvA請用完整的堆棧跟蹤編輯你的問題。 – 2014-10-14 14:35:03

+0

將完整的堆棧跟蹤放入註釋@ sotirios-delimanolis中有點困難。我可以通過在一個'AppConfig'配置中相互依賴(循環依賴:(:()是有兩個bean來重現這一點,我知道,我應該重新考慮我的設計在這裏...... ;-) – 2014-10-15 06:55:11

0

因此將ApplicationContext自動裝入@ConfigurationAppConfig類確實有效並且實際上是自動裝配的。直接在@Bean方法中使用它似乎會產生一個循環的自動裝配情況。和StackOverflowError :-(

的解決方法是使用一個「後結構模式」與@PostConstruct ...

解決方案中的代碼:

@Configuration 
public class AppConfig { 

    @Autowired 
    private ApplicationContext applicationContext; 

    @Bean 
    public Marshaller marshaller() { 
     Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 
     marshaller.setContextPath("com.company.app.jaxb"); 
     return marshaller; 
    } 

    @PostConstruct 
    public void initMarshaller() { 
     marshaller().setSchema(applicationContext.getResource("classpath:/xsd/schema.xsd")); 
    } 
+0

感謝您指出這個方向@ RomanVottner ;-) – 2014-10-15 07:11:17

+0

你找到了一個解決方案真是太棒了,但是你的問題絕對沒有任何關於StackOverflowError的東西。另外在'@ Configuration'類中自動裝配'ApplicationContext'確實會導致'StackOverflowError'。一定有別的事情你在做,你沒有向我們展示。 – 2014-10-15 14:31:29