Migrating from Spring XML configuration style to Spring Java-based configuration (using @Configuration
) I run into an issue loading resources, in my case from the classpath.
In XML I did have a bean declared like:
<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>
Configuration this bean in a Java class looks like:
@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;
}
This will actually throw a NullpointerException during loading of the ApplicationContext
because the @Autowired
field is not (yet?) autowired...
Q: What is the right solution to load resources (from the classpath and/or in general)? Using the ApplicationContext
is promoted in the Spring Documentation: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#context-introduction
Q: And why is the autowired field still null?
For
marshaller.setSchema(applicationContext.getResource("classpath:/xsd/schema.xsd"));
you can instead use
marshaller.setSchema(new ClassPathResource("/xsd/schema.xsd"));
But I am unable to reproduce your injected ApplicationContext
field being null
.
So autowiring the ApplicationContext
into an @Configuration
AppConfig
class does work and is actually being autowired. Using it directly in an @Bean
method seems to produce a circular autowiring situation. And a StackOverflowError
:-(
The solution is to apply a 'post construct pattern' with @PostConstruct
...
Solution in code:
@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"));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.