我在玩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中不推薦使用它。我發現了一堆尋找這個註解的帖子,但是當一個配置對象被注入時沒有任何問題!
謝謝Donal!我編輯了這篇文章,其中包含指向Springsource博客的鏈接,我在其中找到了將Configuration類注入到另一個Configuration類中的示例代碼。它看起來像'應該'工作! – jcurtin