@PropertySource("classpath:tx.properties") @Configuration public class TxConfig { public TxConfig() { System.out.println("Txconfig-------"); } @Autowired private Environment environment; @Bean public DataSource dataSource() throws Exception { Properties props = new Properties(); props.put(DruidDataSourceFactory.PROP_URL,environment.getProperty("druid.url")); props.put(DruidDataSourceFactory.PROP_USERNAME,environment.getProperty("druid.user")); props.put(DruidDataSourceFactory.PROP_PASSWORD,environment.getProperty("druid.passwd")); return DruidDataSourceFactory.createDataSource(props); } @Bean public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource()); sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml")); return sqlSessionFactoryBean; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("org.panrd.dao"); return configurer; } }
运行时Environment注入失败,由于spring在启动时先是实例化BeanDefinitionRegistryPostProcessor,而MapperScannerConfigurer实现了该接口,MapperScannerConfigurer在实例化时使用的事factoryMethod 的方式,所以要先实例化TxConfig,而在TxConfig实例化时,此时容器中hasInstantiationAwareBeanPostProcessors为false,在填充属性的方法populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)会判断hasInstantiationAwareBeanPostProcessors,由于hasInstantiationAwareBeanPostProcessors是false,所以调用不到InstantiationAwareBeanPostProcessor接口的实现类AutowiredAnnotationBeanPostProcessor的后置处理器