回炉Spring--事务及Spring源码
声明式事务
配置文件信息:
/**
* @EnableTransactionManagement 开启基于注解的事务管理功能
* 1、配置数据源
* 2、配置事务管理器来管理事务
* 3、给方法上标注 @Transactional 表示当前方法是一个事务方法,@Transaction默认回滚Error和RuntimeException,但是不包括和RuntimeException
* 一样同属于Exception子类的如IOException、SQLException和自定义异常等,对于这些异常如果也要回滚要在rollbackFor中指定
*/
@EnableTransactionManagement
@Configuration
public class TxConfig { @Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("yang");
dataSource.setPassword("yang");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
} /**
* 如果bean之间有依赖,直接放进参数中即可,参数值会从Spring容器中取,然后赋值
* 参数从Spring容器中取
*
* @param dataSource
* @return
*/
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 也可以直接调用,Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件
// JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
} /**
* 注册事务管理器在容器中
*
* @return
* @throws Exception
*/
@Bean
public PlatformTransactionManager transactionManager() throws Exception {
return new DataSourceTransactionManager(dataSource());
}
}
@EnableTransactionManagement 做了什么?
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement { boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default Ordered.LOWEST_PRECEDENCE;
}
1、导入了TransactionManagementConfigurationSelector,TransactionManagementConfigurationSelector往容器中导入了两个组件
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
AutoProxyRegistrar和ProxyTransactionManagementConfiguration
2、AutoProxyRegistrar
给容器中注册了一个beanNameorg.springframework.aop.config.internalAutoProxyCreator,类型为InfrastructureAdvisorAutoProxyCreator
的组件(bean),其是一个后置处理器,和AOP中的AnnotationAwareAspectJAutoProxyCreator类似,它们beanName相同。
都是在对象创建完成之后利用后置处理器的初始化后置方法,包装对象,然后返回一个包含增强器的代理对象,代理对象执行方法利用拦截器链进行调用。
3、ProxyTransactionManagementConfiguration是一个配置文件类
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
return advisor;
}
1、往容器中注册事务增强器transactionAdvisor,其中事务增强器中又依赖了:
1):事务增强器要用事务注解的参数信息,TransactionAttributeSource,AnnotationTransactionAttributeSource来解析事务注解
2):事务拦截器:TransactionInterceptor,保存了事务属性信息,事务管理器。其实现了MethodInterceptor接口。在目标方法执行
的时候:执行拦截器链,然后执行事务拦截器:
(1):先获取事务相关的属性
(2):再获取PlatformTransactionManager事务管理器,如果在@Transactional注解中没有指定transactionManager,则最终会
从容器中按照类型获取一个PlatformTransactionManager
(3):执行目标方法
如果异常,获取到事务管理器,利用事务管理回滚操作
【transactionInfo.getTransactionManager().rollback(txInfo.getTransactionStatus())】
如果正常,利用事务管理器,提交事务【transactionInfo.getTransactionManager().commit(txInfo.getTransactionStatus());】
@Transactional注解处理器的核心代码,TransactionAspectSupport#invokeWithinTransaction:278,从TransactionInterceptor#invoke进入
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable { // If the transaction attribute is null, the method is non-transactional.
// 开启事务
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
// 执行业务方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
// 回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
// 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
} else {
final ThrowableHolder throwableHolder = new ThrowableHolder(); // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
}); // Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
拓展原理
BeanPostProcessor:bean的后置处理器,在bean创建对象之后的初始化前后做一些拦截工作
一、BeanFactoryPostProcessor:beanFactory的后置处理器,在BeanFactory初始化之后调用【postProcessBeanFactory()】,来定制和修改BeanFactory的内容,这时候所有的bean定义都已经保存到了beanFactory中,但是bean的实例还未创建。
BeanFactoryPostProcessor执行时机和原理:
1、创建Spring容器
2、refresh()-->invokeBeanFactoryPostProcessors(beanFactory);
1):直接在BeanFactory中找到所有类型是BeanFactoryProcessor的组件,并执行它们的方法
2):在初始化创建其他组件前面执行
二、BeanDefinitionRegistryPostProcessor【BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor】
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry);在所有的bean定义信息将要被加载,bean实例还未创建。
因此在BeanFactoryPostProcessor的postProcessBeanFactory()之前执行,可以利用其往容器中再额外添加一些组件,如:
RootBeanDefinition beanDefinition = new RootBeanDefinition(Computer.class);
registry.registerBeanDefinition("computer", beanDefinition);
BeanDefinitionRegistryPostProcessor执行时机和原理:
1、创建Spring容器
2、refresh()-->invokeBeanFactoryPostProcessors(beanFactory);
3、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件
1):依次触发所有的postProcessBeanDefinitionRegistry()方法
2):再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
4、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法
三、ApplicationListener
监听容器中发布的事件。事件驱动模型开发。监听ApplicationEvent及其子类事件
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event); }
监听事件步骤:
1、自定义监听器实现ApplicationListener来监听某个事件(ApplicationEvent及其子类)
2、把监听器注册到Spring容器中@Component
3、只要容器中有相关事件的发布,我们就能监听到这个事件
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件
ContextClosedEvent:关闭容器会发布这个事件
4、如何发布一个事件: applicationContext.publishEvent(); 如:【applicationContext.publishEvent(new ContextStartedEvent(applicationContext));】
监听原理:
以ContextRefreshedEvent事件为例:
1、创建Spring容器
2、refresh()-->finishRefresh(); refresh的最后一步完成容器刷新进行事件发布
3、publishEvent(new ContextRefreshedEvent(this));
事件发布流程:
1):获取事件的多播器(派发器)
2):multicastEvent 派发事件
【getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);】
3):获取到所有的上下文监听器的集合 getApplicationListeners(event, type),然后遍历
(1)、如果线程池Executor不为null,则使用Executor进行异步派发
(2)、否则,以同步的方式直接执行listener方法:【invokeListener(listener, event);】,拿到listener然后调用其的
【listener.onApplicationEvent(event); 】
那流程中的事件多播器如何获取呢?
1、创建Spring容器
2、refresh()-->initApplicationEventMulticaster(); 在registerBeanPostProcessors(beanFactory);之后为容器初始化事件多播器
1)、先去容器中找有没有id=“applicationEventMulticaster”的组件;
2)、如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
容器中有哪些监听器呢?
1、创建Spring容器
2、refresh()-->registerListeners(); 从容器中检查到所有的监听器bean并将它们注册到applicationEventMulticaster中
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
} // Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
监听事件除了自定义监听器实现ApplicationListener,也可以使用@EventListener标注在方法上指定监听的事件,当事件发生时就会触发方法执行
@EventListener(classes = ApplicationEvent.class)
public void listen(ApplicationEvent event) {
// doSomeThing
}
@EventListener的原理是通过EventListenerMethodProcessor 处理器解析方法上的@EventListener注解来实现的。
【public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware】
SmartInitializingSingleton:
public interface SmartInitializingSingleton { /**
* Invoked right at the end of the singleton pre-instantiation phase,
* with a guarantee that all regular singleton beans have been created
* already. {@link ListableBeanFactory#getBeansOfType} calls within
* this method won't trigger accidental side effects during bootstrap.
* <p><b>NOTE:</b> This callback won't be triggered for singleton beans
* lazily initialized on demand after {@link BeanFactory} bootstrap,
* and not for any other bean scope either. Carefully use it for beans
* with the intended bootstrap semantics only.
*/
void afterSingletonsInstantiated(); }
SmartInitializingSingleton原理:
再次说【finishBeanFactoryInitialization(beanFactory);】,完成BeanFactory初始化工作,创建剩下的除了BeanPostProcessor之外的单实例bean;
refresh()--> finishBeanFactoryInitialization(beanFactory);--> beanFactory.preInstantiateSingletons();--> smartSingleton.afterSingletonsInstantiated();
DefaultListableBeanFactory:
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
} // Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans...创建所有的单实例bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
} // Trigger post-initialization callback for all applicable beans...创建完之后,判断其是否是SmartInitializingSingleton类型,是的话,调用afterSingletonsInstantiated();
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
1)、先创建所有的单实例bean;getBean();
2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();
3)、EventListenerMethodProcessor 在重写SmartInitializingSingleton接口的afterSingletonsInstantiated()方法上对bean方法上的@EventListener注解进行处理,实现其监听功能
protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
if (!this.nonAnnotatedClasses.contains(targetType)) {
Map<Method, EventListener> annotatedMethods = null;
try {
annotatedMethods = MethodIntrospector.selectMethods(targetType,
new MethodIntrospector.MetadataLookup<EventListener>() {
@Override
public EventListener inspect(Method method) {
return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
}
});
}
catch (Throwable ex) {
// An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
}
}
if (CollectionUtils.isEmpty(annotatedMethods)) {
this.nonAnnotatedClasses.add(targetType);
if (logger.isTraceEnabled()) {
logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
}
}
else {
// Non-empty set of methods
for (Method method : annotatedMethods.keySet()) {
for (EventListenerFactory factory : factories) {
if (factory.supportsMethod(method)) {
Method methodToUse = AopUtils.selectInvocableMethod(
method, this.applicationContext.getType(beanName));
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener)
.init(this.applicationContext, this.evaluator);
}
this.applicationContext.addApplicationListener(applicationListener);
break;
}
}
}
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
beanName + "': " + annotatedMethods);
}
}
}
}
梳理Spring容器创建及初始化过程:
AbstractApplicationContext:
Spring的refresh() 容器的创建和刷新
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
initMessageSource(); // Initialize event multicaster for this context.
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
onRefresh(); // Check for listener beans and register them.
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
} // Destroy already created singletons to avoid dangling resources.
destroyBeans(); // Reset 'active' flag.
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
1、prepareRefresh() 刷新前的预处理
1)-->initPropertySources(); 初始化一些属性配置资源文件到容器中的environment对象中,子类需自定义属性初始化方法
2)-->getEnvironment().validateRequiredProperties(); 获取属性内容并校验合法性等
3)-->this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); 初始化用来保存容器中的一些早期事件
2、ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 获取beanFactory
1):refreshBeanFactory(); 刷新【创建】BeanFactory;创建了一个this.beanFactory = new DefaultListableBeanFactory();设置并设置serializationId;
2):ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 返回上一步创建的beanFactory
3):默认的beanFactory是DefaultListableBeanFactory
3、prepareBeanFactory(beanFactory); beanFactory的预准备工作,对其属性赋值
1):设置beanFactory的类加载器,支持表达式解析器等
2):添加部分后置处理器,如【beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));】ApplicationListenerDetector等
3):设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware等;
4):注册可以解析的依赖;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5):添加编译时的AspectJ支持
6):给BeanFactory中注册一些能用的组件;
environment【ConfigurableEnvironment】、
systemProperties【Map<String, Object>】、
systemEnvironment【Map<String, Object>】
4、postProcessBeanFactory(beanFactory); BeanFactory准备工作完成后进行的后置处理工作,此时bean的定义信息还未加载
此方法默认没有方法体,子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
以上是beanFactory的创建及预准备工作。
5、invokeBeanFactoryPostProcessors(beanFactory); 实例化并调用所有注册的BeanFactoryPostProcessor执行其方法,
beanFactory的后置处理器,其postProcessBeanFactory()方法在beanFactory标准初始化之后执行的,这时候所有bean定义都将被加载,但是还没有bean被实例化,这时允许重写或者添加bean的属性。
不过BeanFactoryPostProcessor有个子接口BeanDefinitionRegistryPostProcessor,其方法postProcessBeanDefinitionRegistry在所有常规bean定义都将被加载,但是还没有bean被实例化,这时允许在下一个后处理阶段开始之前添加bean的定义信息
1)、先执行BeanDefinitionRegistryPostProcessor
(1)、从beanFactory中获取所有的BeanDefinitionRegistryPostProcessor;
(2)、先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor【postProcessor.postProcessBeanDefinitionRegistry(registry)】
(3)、再次执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor【postProcessor.postProcessBeanDefinitionRegistry(registry)】
(4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors【postProcessor.postProcessBeanDefinitionRegistry(registry)】
2)、再执行BeanFactoryPostProcessor的方法
(1)、从beanFactory中获取所有的BeanFactoryPostProcessor
(2)、先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor【postProcessor.postProcessBeanFactory()】
(3)、再执行实现了Ordered顺序接口的BeanFactoryPostProcessor【postProcessor.postProcessBeanFactory()】
(4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor【postProcessor.postProcessBeanFactory()】
6、registerBeanPostProcessors(beanFactory); 注册并实例化所有的BeanPostProcessor,bean的后置处理器,用来拦截bean的创建过程
不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
BeanPostProcessor、
DestructionAwareBeanPostProcessor、
InstantiationAwareBeanPostProcessor、
SmartInstantiationAwareBeanPostProcessor、
MergedBeanDefinitionPostProcessor:
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
2)、先注册实现了PriorityOrdered优先级接口的BeanPostProcessor;把每一个BeanPostProcessor;添加到BeanFactory中【beanFactory.addBeanPostProcessor(postProcessor);】
3)、再注册实现了Ordered接口的
4)、最后注册没有实现任何优先级接口的
5)、最终注册MergedBeanDefinitionPostProcessor;
6)、注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是applicationContext.addApplicationListener((ApplicationListener<?>) bean);
7、initMessageSource(); 初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
1):获取BeanFactory
2):看容器中是否有id为messageSource的,类型是MessageSource的组件,如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;
MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
3):把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);
8、initApplicationEventMulticaster(); 初始化事件派发器
1)、获取BeanFactory
2)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
3)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
4)、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
9、onRefresh(); 留给子容器(子类)
子类重写这个方法,在容器刷新的时候可以自定义逻辑;
10、registerListeners(); 给容器中将项目里面所有的ApplicationListener注册进来
1)、从容器中拿到所有的ApplicationListener
2)、将每个监听器添加到事件派发器中;【getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);】
3)、派发之前步骤产生的事件;
11、finishBeanFactoryInitialization(beanFactory); 初始化所有剩下的单实例bean,因为BeanPostFactory类型的bean已经已经创建完成了
beanFactory.preInstantiateSingletons();
1):获取容器中所有的beanNames(ArrayList<String>),遍历并依次进行初始化和创建对象
2):根据beanName从【ConcurrentHashMap<String, RootBeanDefinition>】获取每一个bean的定义信息RootBeanDefinition
3):判断如果当前bean不是抽象的,是单例的和是懒加载的则:
(1):判断bean是否实现了FactoryBean接口,如果是则用工厂方法创建对象
(2):如果不是,getBean(beanName); 来创建对象,和【applicationContext.getBean("beanName");】执行代码相同
1、doGetBean(name, null, null, false)
2、getSingleton(String beanName) 获取到了直接返回bean实例
1):先从缓存【private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);】中获取保存的单实例
Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来);
2):如果singletonObjects 中没有,再从当前创建bean池中去获取
【private final Set<String> singletonsCurrentlyInCreation=Collections.newSetFromMap(newConcurrentHashMap<String, Boolean>(16));】
3):如果beanName在当前创建bean池中,则尝试从earlySingletonObjects缓存中获取
【private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);】
4):如果earlySingletonObjects中也没有,则再次尝试从singletonFactories中获取提前曝光的ObjectFactory,如果根据beanName找到了ObjectFactory,
则从ObjectFactory中获取bean实例,然后将其放在earlySingletonObjects 缓存中,再将其ObjectFactory从singletonFactories中移除
因为在创建单实例bean的时候会存在依赖注入的情况,为了避免循环依赖,Spring在创建bean的过程中,若发现有依赖bean,则尝试去创建依赖的bean,因
此Spring将每一个正在创建的bean的beanName放在一个“当前创建bean池”中,bean在创建过程中,BeanName将一直存在这个池中。另外,为了避免循环依
赖,在Spring中创建bean的原则是不等bean创建完就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则
直接使用ObjectFactory去获取依赖bean的实例。
3、如果获取不到,开始创建流程,先标记bean已经创建,避免多线程创建多个bean【markBeanAsCreated(beanName);】
4、获取当前bean的定义信息,并校验合法性【
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);】
5、获取当前bean的所有依赖bean【String[] dependsOn = mbd.getDependsOn();】如果不为空,则依此创建其依赖bean【getBean(depBeanName);】回到步骤(2)
6、启动单实例bean的创建流程,使用用ObjectFactory
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
1):createBean(beanName, mbd, args);
2):Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 尝试让InstantiationAwareBeanPostProcessor先拦截返回代理对象
拿到所有的BeanPostProcessor【getBeanPostProcessors()】并遍历,如果有InstantiationAwareBeanPostProcessor类型的BeanPostProcessor,则让
InstantiationAwareBeanPostProcessor的后置处理器提前执行,先触发其【postProcessBeforeInstantiation(beanClass, beanName);】如果其返回的对象不为
空,则执行所有BeanPostProcessor的postProcessAfterInitialization返回其代理对象,然后结束bean对象的创建。如果返回的对象为空,继续步骤3)
(亲测,即使切面的目标类在此时返回的也是空,会继续后面的doCreateBean),因此切面的代理类是在bean实例化之后的InstantiationAwareBeanPostProcessor的
postProcessAfterInitialization方法中创建代理对象的。
3):Object beanInstance = doCreateBean(beanName, mbdToUse, args);
(1):BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args); 利用工厂方法或者对象的构造器创建出Bean实例
(2):applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 执行MergedBeanDefinitionPostProcessor后置处理器的
postProcessMergedBeanDefinition(mbd, beanType, beanName)方法
(3):populateBean(beanName, mbd, instanceWrapper); 给bean的属性赋值
赋值之前有1、2、3三步:
1、遍历所有的后置处理器,只执行InstantiationAwareBeanPostProcessor类型的后置处理器的postProcessAfterInstantiation方法,如果其返回false,则停止
赋值操作return;
2、依此byName和byType自动装配为bean的依赖注入值
3、遍历所有的后置处理器,只执行InstantiationAwareBeanPostProcessor类型的后置处理器的postProcessPropertyValues,如果返回pvs==null,则停止下
面的赋值操作并return;
3、applyPropertyValues(beanName, mbd, bw, pvs); 应用Bean属性的值;为属性利用setter方法等进行赋值;
(4):initializeBean(beanName, exposedObject, mbd); Bean初始化
1、invokeAwareMethods(beanName, bean); 如果bean实现了xxxAware接口,则调用其的setXxx方法为bean的xxx属性赋值
2、wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);执行所有的BeanPostProcessor后置处理器的
postProcessBeforeInitialization方法
3、invokeInitMethods(beanName, wrappedBean, mbd); 执行初始化方法
1):如果bean实现了InitializingBean接口,则执行其afterPropertiesSet()方法
2):String initMethodName = mbd.getInitMethodName();获取自定义初始化方法,如果有自定义初始化方法,则执行其自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
4、wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);执行所有的BeanPostProcessor后置处理器的
postProcessAfterInitialization方法(创建bean的代理在此执行的)
(5):registerDisposableBeanIfNecessary(beanName, bean, mbd); 注册bean的销毁方法
(6):返回bean实例
4)、afterSingletonCreation(String beanName) 将beanName从singletonsCurrentlyInCreation移除
5)、addSingleton(beanName, singletonObject);
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
所以Spring容器就是这些各种Map,保存了单实例bean,环境信息等。
4):遍历beanNames,根据beanName拿到每一个bean实例,判断其是否实现了SmartInitializingSingleton接口,如果实现了则调用其afterSingletonsInstantiated()方法
完成BeanFactory的初始化创建工作;IOC容器就创建完成;
12、finishRefresh();
1)、initLifecycleProcessor(); 初始化和生命周期有关的后置处理器:LifecycleProcessor
默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();加入到容器;
如果我们写一个LifecycleProcessor的实现类,那么下面的方法在BeanFactory进行到相应的生命周期处就会进行调用
void onRefresh();
void onClose();
2)、getLifecycleProcessor().onRefresh(); 拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
3)、publishEvent(new ContextRefreshedEvent(this)); 发布容器刷新完成事件;
4)、LiveBeansView.registerApplicationContext(this);
总结:
1、Spring容器启动的时候,先会保存所有注册进来的Bean的定义信息
1):xml注册bean:<bean>
2):注解注册Bean;@Service、@Component、@Bean、xxx
2、Spring容器会合适的时机创建这些Bean
1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
3、非常重要的BeanPostProcessor,后置处理器
1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
AsyncAnnotationBeanPostProcessor:异步相关
ScheduledAnnotationBeanPostProcessor:调度相关
等等
4、事件驱动模型;
ApplicationListener;事件监听
ApplicationEventMulticaster;事件派发
问题汇总:
Spring如何实现DI及时机?
AutowiredAnnotationBeanPostProcessor:处理自动注入
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware ;
public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor;
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor;
1、在doGetBean中执行createBean之前,先获取当前bean的所有依赖bean【String[] dependsOn = mbd.getDependsOn();】如果不为空,则依此创建其依赖
bean【getBean(depBeanName);】
2、在populateBean(beanName, mbd, instanceWrapper); 给bean的属性赋值,这一步中,先执行InstantiationAwareBeanPostProcessor的后置处理器,
即用AutowiredAnnotationBeanPostProcessor 为依赖注入值。
回炉Spring--事务及Spring源码的更多相关文章
- spring事务传播实现源码分析
转载. https://blog.csdn.net/qpfjalzm123/article/details/83717367 本文只是对spring事务传播实现的流程进行简单的分析,如有不对之处请指出 ...
- Spring JPA实现逻辑源码分析总结
1.SharedEntityManagerCreator: entitymanager的创建入口 该类被EntityManagerBeanDefinitionRegistrarPostProcesso ...
- Spring框架之beans源码完全解析
导读:Spring可以说是Java企业开发里最重要的技术.而Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmin ...
- Spring框架之jms源码完全解析
Spring框架之jms源码完全解析 我们在前两篇文章中介绍了Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmi ...
- Spring框架之jdbc源码完全解析
Spring框架之jdbc源码完全解析 Spring JDBC抽象框架所带来的价值将在以下几个方面得以体现: 1.指定数据库连接参数 2.打开数据库连接 3.声明SQL语句 4.预编译并执行SQL语句 ...
- Spring Boot @Enable*注解源码解析及自定义@Enable*
Spring Boot 一个重要的特点就是自动配置,约定大于配置,几乎所有组件使用其本身约定好的默认配置就可以使用,大大减轻配置的麻烦.其实现自动配置一个方式就是使用@Enable*注解,见其名知 ...
- 【Spring】Spring IOC原理及源码解析之scope=request、session
一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...
- spring boot 2.0 源码分析(一)
在学习spring boot 2.0源码之前,我们先利用spring initializr快速地创建一个基本的简单的示例: 1.先从创建示例中的main函数开始读起: package com.exam ...
- spring boot 2.0 源码分析(二)
在上一章学习了spring boot 2.0启动的大概流程以后,今天我们来深挖一下SpringApplication实例变量的run函数. 先把这段run函数的代码贴出来: /** * Run the ...
- spring boot 2.0 源码分析(四)
在上一章的源码分析里,我们知道了spring boot 2.0中的环境是如何区分普通环境和web环境的,以及如何准备运行时环境和应用上下文的,今天我们继续分析一下run函数接下来又做了那些事情.先把r ...
随机推荐
- 制作自己的win7系统
每次安装完纯净版的系统,然后是漫长的打补丁,装驱动,装软件.不妨制作一个自己的系统光盘(也就是GHOST系统),再要重装系统时,直接用这个系统光盘,一键安装,方便省时. 制作GHOST系统,就是将本地 ...
- 从有状态应用(Session)到无状态应用(JWT),以及 SSO 和 OAuth2
不管用哪种方式认证用户,都可能被中间人攻击窃取 SessionID 或 Token,从而发生 CSRF 攻击.解决方式就是全站 HTTPS.现在 Let's Encrypt 已经支持免费的通配符 HT ...
- postman测试wsdl类型接口
1 IP地址来源搜索 WEB 服务 接口信息 http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl 2 设置接口调用地址 ...
- hdu6570Wave (暴力求解)
Problem Description Avin is studying series. A series is called "wave" if the following co ...
- CVTRES : fatal error CVT1100: duplicate resource
升级某些VC6工程到VS2017,除了目录问题外,就是这个. 解决方法: Properties > Linker > Manifest File 第一项,Generate Manifest ...
- HTML5-Classlist样式操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript LoopQueue
function Queue() { var items = []; this.enqueue = function(element) { items.push(element) } this.deq ...
- 前端webpack & vue
地址 : https://blog.csdn.net/jiang7701037
- swagger2文档使用
①.导入依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-sw ...
- mysql 5.7 创建函数报错,This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creat
今天用命令创建函数, 报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration ...