简体   繁体   中英

Spring bean wiring in different contexts

For datasource layer I use the following Spring Configuration file:

@Configuration
@ComponentScan(basePackages = {"com.savdev.springmvcexample.repository", "com.savdev.springmvcexample.config"})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.savdev.springmvcexample.repository"})
public class InfrastructureContextConfiguration {
...
    @Configuration
    @Profile(value = "file_based")
    @PropertySource("classpath:/db/config/file_based.properties")
    public static class FileBasedConfiguration {

        @Inject
        private Environment environment;

        @Bean
        public DataSource dataSource() {
            BasicDataSource dataSource = new org.apache.commons.dbcp.BasicDataSource();
            dataSource.setDriverClassName(environment.getProperty("jdbc.driver"));
            dataSource.setUrl(environment.getProperty("jdbc.url"));
            dataSource.setUsername(environment.getProperty("jdbc.username"));
            dataSource.setPassword(environment.getProperty("jdbc.password"));
            return dataSource;
        }
    }
...

To run tests I load this configuration via @ContextConfiguration :

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { InfrastructureContextConfiguration.class, HsqldbEmbeddableDbStarterContextConfiguration.class })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional()
@ActiveProfiles(profiles = {"file_based", "test_data"} )
public abstract class AbstractJpaJavaTestBase {
...

And it works fine.

The same InfrastructureContextConfiguration class is used in web module when DispatcherServlet is created:

public class SpringMvcExampleWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        registerDispatcherServlet(servletContext);
    }

    private void registerDispatcherServlet(final ServletContext servletContext) {
        WebApplicationContext dispatcherContext = createContext(WebMvcContextConfiguration.class, InfrastructureContextConfiguration.class);
        DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherContext);
        dispatcherServlet.setContextInitializers( new SpringMvcExampleProfilesInitializer());
        ServletRegistration.Dynamic dispatcher;
        dispatcher = servletContext.addServlet("dispatcher", dispatcherServlet);
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    private WebApplicationContext createContext(final Class<?>... annotatedClasses) {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(annotatedClasses);
        return context;
    }
}

But now, I'm getting NullPointerException in the following line of InfrastructureContextConfiguration :

dataSource.setDriverClassName(environment.getProperty("jdbc.driver"));

The environment is not wired. What can I do to resolve it?

What I found. The similar issue already have been met: same1, some solutions

seems the problem is not connected, but the last answer is the best solution

total: Actually, the field that is injected with @Inject cannot be null. It must throws exception. As a result if it is null then - the annotation has not been applied at all. As a result the main reason is the absence of its implementation in classpath.

So I added the following in my web.pom. and it resolved the problem:

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

As alternative options I could use:

  1. @Resource instead of @Inject, and environment has been set.

  2. Passed the envirionment as argument into the constructor, instead of wiring it via annotation. But the best case, IMHO, is fix jar dependecy.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM