Spring基于Java的配置加载资源(从类路径)

问题描述:

从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

对于

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

因此将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