2011-09-01 42 views
3

我在玩Spring 3.1和Servlet 3.0,對新的Java配置選項以及使用Spring配置文件非常感興趣,並且正在運行一個挑戰。即使我在網上看到的所有示例都使它看起來像使用@Configuration註釋的類可以有其他對象@Autowired到我看到的是自動裝配不會發生,直到後面的幾個bean已經生成了@Configuration類。Spring 3.1 Java配置 - @Autowired,@Configuration和@Profile挑戰

這裏是我的初始化:

public class SpringMvcInitializer implements WebApplicationInitializer { 

private static org.apache.log4j.Logger log= Logger.getLogger(SpringMvcInitializer.class); 

@Override 
public void onStartup(ServletContext servletContext) throws ServletException { 
    // Create the 'root' Spring application context 
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); 
    rootContext.scan("org.jc.config"); 
    servletContext.addListener(new ContextLoaderListener(rootContext)); 

    // Secures the application 
    servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain")) 
     .addMappingForUrlPatterns(null, false, "/*");  

    ServletRegistration.Dynamic appServlet = 
      servletContext.addServlet("appServlet", new DispatcherServlet(new GenericWebApplicationContext())); 
    appServlet.setLoadOnStartup(1); 

    appServlet.addMapping("/"); 

    log.info("Mvc Initializer starting"); 
} 

我的Web配置

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages="org.jc") 
public class WebConfig extends WebMvcConfigurerAdapter { 

@Bean 
public InternalResourceViewResolver configureInternalResourceViewResolver() { 
    InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 
    resolver.setPrefix("/WEB-INF/"); 
    resolver.setSuffix(".jsp"); 
    return resolver; 
} 

@Override 
public void configureResourceHandling(ResourceConfigurer configurer) { 
    configurer.addPathMapping("/resources/**"); 
    configurer.addResourceLocation("/resources/"); 
} 

我的配置類的JPA

@Configuration 
public class JpaConfig { 
private static Logger logger = Logger.getLogger(JpaConfig.class); 

private AppEnvironmentI appEnvironment; 

@Autowired 
public void setAppEnvironment(AppEnvironmentI appEnvironment) { 
    this.appEnvironment = appEnvironment; 
    checkAppEnv("setAppEnvironment"); 
} 

@Bean 
public AppUser globalUser(){ 
    checkAppEnv("globalUser entry"); 
    AppUser appUser = new AppUser(); 
    checkAppEnv("globalUser exit"); 
    return appUser; 
} 

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ 
    checkAppEnv("entityManagerFactory entry"); 
    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
    emf.setDataSource(dataSource()); 
    emf.setJpaVendorAdapter(this.jpaAdapter()); 
    emf.setPersistenceUnitName("JcEntities2"); 
    checkAppEnv("entityManagerFactory exit"); 
    return emf; 
} 

@Bean 
public DataSource dataSource(){ 
    checkAppEnv("dataSource entry"); 
    DriverManagerDataSource ds = new DriverManagerDataSource(); 
    ds.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver"); 
    ds.setUrl("jdbc:derby://localhost:1527/JcTestDb"); 
    ds.setUsername("jc"); 
    ds.setPassword("pwd"); 
    checkAppEnv("dataSource exit"); 
    return ds; 
} 

@Bean 
public JpaVendorAdapter jpaAdapter() { 
    checkAppEnv("jpaAdapter entry"); 
    HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter(); 
    hibernateJpaVendorAdapter.setShowSql(true); 
    hibernateJpaVendorAdapter.setDatabase(Database.DERBY); 
    checkAppEnv("jpaAdapter exit"); 
    return hibernateJpaVendorAdapter; 
} 

@Bean 
public PlatformTransactionManager transactionManager() { 
    checkAppEnv("transactionManager entry and exit"); 
    return new JpaTransactionManager(entityManagerFactory().getObject()); 
} 

private void checkAppEnv(String _method){ 
    if(this.appEnvironment == null){ 
     logger.info(_method + " - App Environment is null!!!!"); 
    }else{ 
     logger.info(_method + " - App Environment JpaConfig = " + appEnvironment.externalPropertiesFile().getPropertyValue("environment")); 
    } 
} 

我的個人資料類

@Configuration 
@Profile("local") 
public class AppEnvironmentLocal implements AppEnvironmentI{ 
private static Logger logger = Logger.getLogger(AppEnvironmentLocal.class); 

@Bean 
public AppEnvironment externalPropertiesFile(){ 
    logger.info("Fetching properties file for LOCAL environment"); 
    Properties props = FileUtilsJc.getPropertiesFromFlatFile("C:\\AppConf\\JcConf\\JcConfLocal.properties"); 
    AppEnvironment exf = new AppEnvironment(props); 
    return exf; 
} 
} 

記錄器輸出:看起來Spring 3.1在AppEnvironment注入類之前首先嚐試創建Entity Manager Factory bean。因此它會創建除全局用戶(我爲測試而投入的虛擬bean)和事務管理器之外的所有Bean,注入AppEnvironment,然後創建全局用戶和事務管理器Bean。

任何想法非常感謝!

01-Sep-2011 10:20:55 INFO Mvc Initializer starting 
01-Sep-2011 10:20:55 INFO entityManagerFactory entry - App Environment is null!!!! 
01-Sep-2011 10:20:55 INFO dataSource entry - App Environment is null!!!! 
01-Sep-2011 10:20:55 INFO dataSource exit - App Environment is null!!!! 
01-Sep-2011 10:20:55 INFO jpaAdapter entry - App Environment is null!!!! 
01-Sep-2011 10:20:55 INFO jpaAdapter exit - App Environment is null!!!! 
01-Sep-2011 10:20:55 INFO entityManagerFactory exit - App Environment is null!!!! 
01-Sep-2011 10:20:55 INFO Fetching properties file for LOCAL environment 
01-Sep-2011 10:20:55 INFO setAppEnvironment - App Environment JpaConfig = LOCAL 

下面是示例代碼我用這樣組裝起來的網址:

http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ 

我發現文件指出,之前在Spring 3.1有必要的@AnnotationDrivenConfig註釋添加到您的注射類爲了使@Autowired能夠工作,但在Spring 3.1中不推薦使用它。我發現了一堆尋找這個註解的帖子,但是當一個配置對象被注入時沒有任何問題!

回答

2

據我瞭解,@Configuration豆前非配置豆類構建和標記是尚未在該點豆,他們返回@Bean生產對象的方法; bean的構建順序是未定義的(除了一些特殊的bean類型;標準屬性文件加載器很早被調用,以便它們發現的值可以用來設置一個@Configuration bean)。直接調用bean方法令人不悅;讓Spring爲你做,因爲它會在@Bean方法返回後連線

+0

謝謝Donal!我編輯了這篇文章,其中包含指向Springsource博客的鏈接,我在其中找到了將Configuration類注入到另一個Configuration類中的示例代碼。它看起來像'應該'工作! – jcurtin