Spring 3.1配置:环境未注入

时间:2011-11-09 20:12:58

标签: java spring configuration environment

我在弹簧3.1配置中使用以下内容:

@Configuration
@EnableTransactionManagement
public class DataConfig {
    @Inject
    private Environment env;
    @Inject
    private DataSource dataSource;

    // @Bean
    public SpringLiquibase liquibase() {
        SpringLiquibase b = new SpringLiquibase();
        b.setDataSource(dataSource);
        b.setChangeLog("classpath:META-INF/db-changelog-master.xml");
        b.setContexts("test, production");
        return b;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean b = new LocalContainerEntityManagerFactoryBean();
        b.setDataSource(dataSource);
        HibernateJpaVendorAdapter h = new HibernateJpaVendorAdapter();
        h.setShowSql(env.getProperty("jpa.showSql", Boolean.class));
        h.setDatabasePlatform(env.getProperty("jpa.database"));

        b.setJpaVendorAdapter(h);
        return (EntityManagerFactory) b;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
        PersistenceExceptionTranslationPostProcessor b = new PersistenceExceptionTranslationPostProcessor();
        // b.setRepositoryAnnotationType(Service.class);
        // do this to make the persistence bean post processor pick up our @Service class. Normally
        // it only picks up @Repository
        return b;

    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager b = new JpaTransactionManager();
        b.setEntityManagerFactory(entityManagerFactory());
        return b;
    }

    /**
     * Allows repositories to access RDBMS data using the JDBC API.
     */
    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource);
    }


    @Bean(destroyMethod = "close")
    public DataSource dataSource() {

        BasicDataSource db = new BasicDataSource();
        if (env != null) {
            db.setDriverClassName(env.getProperty("jdbc.driverClassName"));
            db.setUsername(env.getProperty("jdbc.username"));
            db.setPassword(env.getProperty("jdbc.password"));
        } else {
            throw new RuntimeException("environment not injected");
        }
        return db;
    }
}

问题是变量env未注入,并且始终为null。

我没有对环境设置做任何事情,因为我不知道它是否需要或如何使用。我看了温室的例子,我没有找到任何专门针对环境的东西。我该怎么做以确保注入env

相关文件:

// CoreConfig.java
@Configuration
public class CoreConfig {

    @Bean
    LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }

    /**
     * Properties to support the 'standard' mode of operation.
     */
    @Configuration
    @Profile("standard")
    @PropertySource("classpath:META-INF/runtime.properties")
    static class Standard {
    }

}


// the Webconfig.java
@Configuration
@EnableWebMvc
@EnableAsync
// @EnableScheduling
@EnableLoadTimeWeaving
@ComponentScan(basePackages = "com.jfd", excludeFilters = { @Filter(Configuration.class) })
@Import({ CoreConfig.class, DataConfig.class, SecurityConfig.class })
@ImportResource({ "/WEB-INF/spring/applicationContext.xml" })
public class WebConfig extends WebMvcConfigurerAdapter {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations(
                "/images/");
    }

    @Bean
    public BeanNameViewResolver beanNameViewResolver() {
        BeanNameViewResolver b = new BeanNameViewResolver();
        b.setOrder(1);
        return b;
    }

    @Bean
    public InternalResourceViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver b = new InternalResourceViewResolver();
        b.setSuffix(".jsp");
        b.setPrefix("/WEB-INF/jsp/");
        b.setOrder(2);
        return b;
    }

    @Bean
    public CookieLocaleResolver localeResolver() {
        CookieLocaleResolver b = new CookieLocaleResolver();
        b.setCookieMaxAge(100000);
        b.setCookieName("cl");
        return b;
    }

    // for messages
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource b = new ResourceBundleMessageSource();
        b.setBasenames(new String[] { "com/jfd/core/CoreMessageResources",
                "com/jfd/common/CommonMessageResources",
                "com/jfd/app/AppMessageResources",
                "com/jfd/app/HelpMessageResources" });
        b.setUseCodeAsDefaultMessage(false);
        return b;
    }

    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();

        Properties mappings = new Properties();
        mappings.put("org.springframework.web.servlet.PageNotFound", "p404");
        mappings.put("org.springframework.dao.DataAccessException",
                "dataAccessFailure");
        mappings.put("org.springframework.transaction.TransactionException",
                "dataAccessFailure");
        b.setExceptionMappings(mappings);
        return b;
    }

    /**
     * ViewResolver configuration required to work with Tiles2-based views.
     */
    @Bean
    public ViewResolver viewResolver() {
        UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
        viewResolver.setViewClass(TilesView.class);
        return viewResolver;
    }

    /**
     * Supports FileUploads.
     */
    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(500000);
        return multipartResolver;
    }

    // for configuration
    @Bean
    public CompositeConfigurationFactoryBean myconfigurations()
            throws ConfigurationException {
        CompositeConfigurationFactoryBean b = new CompositeConfigurationFactoryBean();
        PropertiesConfiguration p = new PropertiesConfiguration(
                "classpath:META-INF/app-config.properties");
        p.setReloadingStrategy(new FileChangedReloadingStrategy());

        b.setConfigurations(new org.apache.commons.configuration.Configuration[] { p });
        b.setLocations(new ClassPathResource[] { new ClassPathResource(
                "META-INF/default-config.properties") });
        return b;
    }

    @Bean
    org.apache.commons.configuration.Configuration configuration()
            throws ConfigurationException {
        return myconfigurations().getConfiguration();
    }


// and the SecurityConfig.java
@Configuration
@ImportResource({ "/WEB-INF/spring/applicationContext-security.xml" })
public class SecurityConfig {

    @Bean
    public BouncyCastleProvider bcProvider() {
        return new BouncyCastleProvider();
    }

    @Bean
    public PasswordEncryptor jasyptPasswordEncryptor() {

        ConfigurablePasswordEncryptor b = new ConfigurablePasswordEncryptor();
        b.setAlgorithm("xxxxxx");
        return b;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder b = new org.jasypt.spring.security3.PasswordEncoder();
        b.setPasswordEncryptor(jasyptPasswordEncryptor());
        return b;
    }

}

在applicationcontext.xml中,它只导入了两个xmls来配置缓存和cassandra,所以它可能并不重要。

6 个答案:

答案 0 :(得分:5)

不确定原因,但使用@Resource注释对我有用。 @Autowired总是返回null。

答案 1 :(得分:2)

问题在于记住我功能的弹簧安全性。如果我把这一行<code> <remember-me data-source-ref="dataSource" /> </code>拿出来。一切正常。如果这一行显示,它将尝试在其他任何东西之前加载db并且从未注入env。

答案 2 :(得分:1)

如果您不使用完整的Java EE兼容服务器,则必须在项目类路径中包含javax.inject.jar以添加@Inject的支持。您还可以尝试使用spring的原始@Autowired注释。

答案 3 :(得分:1)

@jfd,

我没有立即发现您的配置有任何问题导致无法注入环境。

如果您从头开始使用空的@Configuration类,然后@Inject the Environment,它是否适合您?

如果是,那么它在什么时候开始失败?

您是否愿意将示例缩小到失败的最小可能配置并将其作为复制项目提交?这里的说明使这一点变得尽可能简单:https://github.com/SpringSource/spring-framework-issues#readme

谢谢!

答案 4 :(得分:1)

我发现我的项目出现类似的错误here。 我还想知道,为了获得sessionFactory,需要调用afterproperties。 ...是的,我也在使用Spring Security(这可能是问题的根源)。

我的@Configuration注释类将@ComponentScan用于包含基于Hibernate的DAO的包和用于创建DAO使用的SessionFactory的@Bean注释方法。在运行时,抛出一个异常,提到找不到'sessionFactory'或'hibernateTemplate'。似乎在创建SessionFactory之前构造了DAO。我的一个解决方法是将组件扫描指令放回XML文件()中,并将@ComponentScan替换为该文件的@ImportResource。

@Configuration
//@ComponentScan(basePackages = "de.webapp.daocustomer", excludeFilters = {@ComponentScan.Filter(Configuration.class), @ComponentScan.Filter(Controller.class)})
@ImportResource({"classpath*:componentScan.xml","classpath*:properties-config.xml","classpath*:security-context.xml"})
public class AppConfig
{
...
@Bean
public SessionFactory sessionFactory() throws Exception
{
    AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();
    bean.setDataSource(dataSource());
    bean.setPackagesToScan(new String[] {"de.webapp"});
    bean.setHibernateProperties(hibernateProps());
    bean.afterPropertiesSet();
    return bean.getObject();
}

同样有趣的事实是:如果包含@ComponentScan,则永远不会在方法sessionFactory()中设置断点!

答案 5 :(得分:1)

我也遇到了与spring-social-sample app类似的问题。

在我将字段级别@Inject转换为构造函数级别之后,注入它就可以了。