Spring静态Bean的原理

最近遇到一个spring static bean的坑,我们知道使用Java Config的方式定义一个Bean 非常简单,只需在Configuration的method上加上 @Bean 注解即可。 但是这里有个例外,假如你的Bean不是一个普通的Bean,而是一个BeanFactoryPostProcessor就需要使用static方法来定义这个Bean。 否则你会得到一个警告: @Bean method TestConfig.customEditorConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details. 也就是说,如果你的bean是一个BFPP,必须定义为static,否则,使用@Autowired, @Resource and @PostConstruct 会有问题。 来看 @Bean注解源码里的注释: 1234567891011121314Special consideration must be taken for @Bean methods that return Spring BeanFactoryPostProcessor (BFPP) types. Because BFPP objects must be instantiated very early in the container lifecycle,they can interfere with processing of annotations such as @Autowired, @Value, and @PostConstruct within @Configuration classes. To avoid these lifecycle issues, mark BFPP-returning @Bean methods as static. For example: @Bean public static PropertySourcesPlaceholderConfigurer pspc() { // instantiate, configure and return pspc ... } By marking this method as static, it can be invoked without causing instantiation of its declaring @Configuration class, thus avoiding the above-mentioned lifecycle conflicts. Note however that static @Bean methods will not be enhanced for scoping and AOP semantics as mentioned above. This works out in BFPP cases, as they are not typically referenced by other @Bean methods. As a reminder, a WARN-level log message will be issued for any non-static @Bean methods having a return type assignable to BeanFactoryPostProcessor. 因为BFPP都需要在在Spring容器的早期进行实例化,因为他们会干扰正常的Bean实例化中处理 @Autowired @Value @PostConstruct ,这篇Blog尝试寻找一下Static Bean背后的原理。

源码解析

Spring 事件驱动的原理

Spring事件驱动Spring 事件驱动的代码都位于spring-context 模块的event包中,主要包括:事件(Event)发布者() Publisher) ,订阅者(Listener)组成。 事件ApplicationEventjava的所有事件对象一般都是java.util.EventObject的子类,Spring的整个继承体系如下:

源码解析

Spring @Transactional是如何工作的?

Spring事务使用Spring配置事务还是挺简单的,第一步创建事务管理器TransactionManager,然后在配置中增加一个@EnableTransactionManagement就可以启用Spring事务了,所以关键类就是@EnableTransactionManagement 1234@Bean public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } 我们可以看到@EnableTransactionManagement 上实际上是import了TransactionManagementConfigurationSelector类,在这个Selector中实际import了两个配置类: AutoProxyRegistrar ProxyTransactionManagementConfiguration 1234567891011121314@Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: return new String[] {determineTransactionAspectClass()}; default: return null; } } 下面我们来根据这个入口来分析一下Spring是如何处理事务的:

源码解析

本站由 Hank Zhao 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
本站总访问量