第一章 Spring源码解读
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
spring容器与web容器:
spring容器:org.springframework.context.ApplicationContext; web容器:javax.servlet.ServletContext(org.apache.catalina.core.ApplicationContext implements ServletContext)。
ContextLoaderListener的作用? ContextLoaderListener作为一个中间者用来建立spring容器与web容器间的关系,真正起作用的是 ContextLoader。ContextLoader主要用于创建spring容器WebApplicationContext,并绑定web.xml中的contextConfigLocation所指定的spring配置文件,最后调用AbstractApplicationContext.refresh方法完成spring容器的各个核心组件的创建。
public class ContextLoader {
public WebApplicationContext initWebApplicationContext ( ServletContext servletContext) {
if ( this . context == null ) {
this . context = createWebApplicationContext ( servletContext) ;
}
if ( this . context instanceof ConfigurableWebApplicationContext ) {
configureAndRefreshWebApplicationContext ( cwac, servletContext) ;
}
}
protected void configureAndRefreshWebApplicationContext ( ConfigurableWebApplicationContext wac, ServletContext sc) {
String configLocationParam = sc. getInitParameter ( CONFIG_LOCATION_PARAM) ;
if ( configLocationParam != null ) {
wac. setConfigLocation ( configLocationParam) ;
}
wac. refresh ( ) ;
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader {
public void refresh ( ) throws BeansException , IllegalStateException {
postProcessBeanFactory ( beanFactory) ;
invokeBeanFactoryPostProcessors ( beanFactory) ;
registerBeanPostProcessors ( beanFactory) ;
initMessageSource ( ) ;
initApplicationEventMulticaster ( ) ;
onRefresh ( ) ;
registerListeners ( ) ;
finishBeanFactoryInitialization ( beanFactory) ;
finishRefresh ( ) ;
}
protected void finishBeanFactoryInitialization ( ConfigurableListableBeanFactory beanFactory) {
beanFactory. preInstantiateSingletons ( ) ;
}
}
Spring AOP的实现:
首先创建一个BeanPostProcessor接口的实现类AnnotationAwareAspectJAutoProxyCreator对象,将其添加到AbstractBeanFactory的beanPostProcessors容器中; 当调用createBean时(createBean调用doCreateBean),都会调用DefaultListableBeanFactory.resolveBeforeInstantiation方法对Bean对象做前置处理。此时便会调用到AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation()方法检查当前对象是否在切入点表达式的拦截范围内; 如果在则根据通知,为该bean对象创建对应的代理对象并直接返回(跳过doCreateBean)。优先使用JDK动态代理,如果proxyTargetClass属性值为true或者目标类没有实现接口,就使用CGLib动态代理。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor , BeanFactoryAware {
public Object postProcessBeforeInstantiation ( Class < ? > beanClass, String beanName) {
Object cacheKey = getCacheKey ( beanClass, beanName) ;
if ( ! StringUtils . hasLength ( beanName) || ! this . targetSourcedBeans. contains ( beanName) ) {
if ( this . advisedBeans. containsKey ( cacheKey) ) {
return null ;
}
if ( isInfrastructureClass ( beanClass) || shouldSkip ( beanClass, beanName) ) {
this . advisedBeans. put ( cacheKey, Boolean . FALSE) ;
return null ;
}
}
TargetSource targetSource = getCustomTargetSource ( beanClass, beanName) ;
if ( targetSource != null ) {
if ( StringUtils . hasLength ( beanName) ) {
this . targetSourcedBeans. add ( beanName) ;
}
Object [ ] specificInterceptors = getAdvicesAndAdvisorsForBean ( beanClass, beanName, targetSource) ;
Object proxy = createProxy ( beanClass, beanName, specificInterceptors, targetSource) ;
this . proxyTypes. put ( cacheKey, proxy. getClass ( ) ) ;
return proxy;
}
return null ;
}
}
spring IOC容器初始化:
spring用BeanDefinition描述一个Bean元数据对象,包括这个Bean的lazy、scope、构造函数参数列表等信息; AbstractApplicationContext的invokeBeanFactoryPostProcessors()方法调用ClassPathBeanDefinitionScanner.doScan(); 注解Bean、XML Bean都由doScan()方法来完成Bean的扫描:
findCandidateComponents(),递归查找指定包下的Component; postProcessBeanDefinition(),为BeanDefinition设置配置属性(@Primary、@Lazy、@DependOn); registerBeanDefinition(),将BeanDefinition注册到DefaultListableBeanFactory的beanDefinitionMap。
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
protected Set < BeanDefinitionHolder > doScan ( String . . . basePackages) {
for ( String basePackage : basePackages) {
Set < BeanDefinition > candidates = findCandidateComponents ( basePackage) ;
for ( BeanDefinition candidate : candidates) {
postProcessBeanDefinition ( ( AbstractBeanDefinition ) candidate, beanName) ;
registerBeanDefinition ( definitionHolder, this . registry) ;
}
}
return beanDefinitions;
}
}
最终,AbstractApplicationContext调用finishBeanFactoryInitialization()方法,对BeanDefinition容器中的所有非Lazy的单例对象初始化。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory {
public void preInstantiateSingletons ( ) throws BeansException {
List < String > beanNames = new ArrayList < > ( this . beanDefinitionNames) ;
for ( String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition ( beanName) ;
if ( ! bd. isAbstract ( ) && bd. isSingleton ( ) && ! bd. isLazyInit ( ) ) {
getBean ( beanName) ;
}
}
}
}
spring是如何解决循环依赖的? Spring-bean的循环依赖以及解决方式 框架源码专题:SPRING是如何解决循环依赖的?为什么无法解决多例和构造器的循环依赖 总结:Spring只能处理通过属性注入或者setter注入的Bean,构造函数注入Bean的循环依赖无法处理。
AbstractBeanFactory创建主Bean对象时,调用AbstractAutowireCapableBeanFactory.doCreateBean()方法; doCreateBean()方法会先调用createBeanInstance()方法,创建主Bean的实例(利用反射constructor.newInstance()方法); 然后调用addSingletonFactory()方法,将主Bean的单例工厂(如果需要提前引用主Bean,则调用单例工厂的后置处理器beanPostProcessors)保存到三级缓存singletonFactories; 接着调用populateBean()方法对主bean进行属性注入或者setter注入。此时,被注入的Bean可以从三级缓存singletonFactories中获取主Bean,并提前对其初始化后放入二级缓存放入earlySingletonObjects,然后访问或使用主Bean,这样被注入的Bean也是一个完整的对象,从而解决了循环依赖问题。 最后,doCreateBean()方法执行完毕后,调用DefaultSingletonBeanRegistry.addSingleton()方法。将单例bean对象放入一级缓存singletonObjects中,并移除存放提前曝光对象的二级缓存earlySingletonObjects和该bean对象的创建工厂缓存singletonFactories。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean ( String beanName, RootBeanDefinition mbd, @Nullable Object [ ] args)
throws BeanCreationException {
instanceWrapper = createBeanInstance ( beanName, mbd, args) ;
applyMergedBeanDefinitionPostProcessors ( mbd, beanType, beanName) ;
addSingletonFactory ( beanName, ( ) -> getEarlyBeanReference ( beanName, mbd, bean) ) ;
populateBean ( beanName, mbd, instanceWrapper) ;
exposedObject = initializeBean ( beanName, exposedObject, mbd) ;
}
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
private final Map < String , Object > singletonObjects = new ConcurrentHashMap < String , Object > ( 256 ) ;
private final Map < String , Object > earlySingletonObjects = new HashMap < String , Object > ( 16 ) ;
private final Map < String , ObjectFactory < ? > > singletonFactories = new HashMap < String , ObjectFactory < ? > > ( 16 ) ;
protected Object getSingleton ( String beanName, boolean allowEarlyReference) {
Object singletonObject = this . singletonObjects. get ( beanName) ;
if ( singletonObject == null && isSingletonCurrentlyInCreation ( beanName) ) {
synchronized ( this . singletonObjects) {
singletonObject = this . earlySingletonObjects. get ( beanName) ;
if ( singletonObject == null && allowEarlyReference) {
ObjectFactory < ? > singletonFactory = this . singletonFactories. get ( beanName) ;
if ( singletonFactory != null ) {
singletonObject = singletonFactory. getObject ( ) ;
this . earlySingletonObjects. put ( beanName, singletonObject) ;
this . singletonFactories. remove ( beanName) ;
}
}
}
}
return ( singletonObject != NULL_OBJECT ? singletonObject : null ) ;
}
}
@PostConstruct、@PreDestroy注、@Resource注解的实现:
当对象实例化完成后属性填充前,会调用DefaultListableBeanFactory.applyMergedBeanDefinitionPostProcessors()方法,然后调用CommonAnnotationBeanPostProcessor.findLifecycleMetadata()方法将当前Bean对象中所有标注了@PostConstruct、@PreDestroy的方法和成员变量保存到LifecycleMetadata对象中; 然后把LifecycleMetadata对象存入lifecycleMetadataCache容器; 在populateBean阶段,调用postProcessProperties完成对@Resource注解的扫描,并注入值 最终,当对象实例化、属性填充完成后的初始化阶段(initializeBean),调用AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization() ⇒ CommonAnnotationBeanPostProcessor.invokeInitMethods()调用LifecycleMetadata封装的当前对象的标注了@PostConstruct注解的方法。 当Spring容器关闭的时候,AbstractApplicationContext.doClose() ⇒ DefaultListableBeanFactory.destroySingletons() ⇒ DisposableBeanAdapter.destroy() ⇒ CommonAnnotationBeanPostProcessor.invokeDestroyMethods()。
@Autowired、@Value和@Inject注解的实现:
同上,不过是在populateBean阶段,调用postProcessProperties方法,然后调用AutowiredAnnotationBeanPostProcessor.postProcessProperties()完成InjectionMetadata对象的封装,然后放入injectionMetadataCache缓存 @Resource优先byName,@Autowired和@Inject优先byName。
HandlerMapping的设计与实现?
在doCreateBean的initializeBean阶段,会调用AbstractHandlerMethodMapping的detectHandlerMethods方法; detectHandlerMethods首先会获取bean中所有方法的Method和RequestMappingInfo对应关系,然后将RequestMappingInfo注册到AbstractHandlerMethodMapping的mappingRegistry容器中; 最终当StandardWrapper触发initServlet()方法时,会调用DispatcherServlet的initHandlerMappings()方法,将mappingRegistry容器放入DispatcherServlet的handlerMappings集合中,等待后续getHandler。
public abstract class AbstractHandlerMethodMapping < T > extends AbstractHandlerMapping implements InitializingBean {
protected void detectHandlerMethods ( Object handler) {
Class < ? > handlerType = ( handler instanceof String ?
obtainApplicationContext ( ) . getType ( ( String ) handler) : handler. getClass ( ) ) ;
if ( handlerType != null ) {
Class < ? > userType = ClassUtils . getUserClass ( handlerType) ;
Map < Method , T > methods = MethodIntrospector . selectMethods ( userType,
( MethodIntrospector. MetadataLookup < T > ) method -> {
try {
return getMappingForMethod ( method, userType) ;
}
catch ( Throwable ex) {
throw new IllegalStateException ( "Invalid mapping on handler class [" +
userType. getName ( ) + "]: " + method, ex) ;
}
} ) ;
methods. forEach ( ( method, mapping) -> {
Method invocableMethod = AopUtils . selectInvocableMethod ( method, userType) ;
registerHandlerMethod ( handler, invocableMethod, mapping) ;
} ) ;
}
}
}
DispatcherServlet的设计与实现?
当客户端向服务端发送一个http请求,经过过滤器链最终到达DispatcherServlet的doDispatch()方法; doDispatch调用getHandler()获取一个与请求URL相映射的处理器映射器对象HandlerMapping; doDispatch再调用getHandlerAdapter()获取一个处理器适配器对象HandlerAdapter,并调用处理器适配器的handle()方法处理请求,最终返回一个ModelAndView对象; doDispatch最后调用processDispatchResult方法内的render方法,通过视图解析器对象ViewResolver将ModelAndView解析成一个视图对象View; 最终通过response.getWriter().append(builder.toString())将View渲染到Response中。
public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch ( HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null ;
ModelAndView mv = null ;
Exception dispatchException = null ;
mappedHandler = getHandler ( processedRequest) ;
HandlerAdapter ha = getHandlerAdapter ( mappedHandler. getHandler ( ) ) ;
mv = ha. handle ( processedRequest, response, mappedHandler. getHandler ( ) ) ;
processDispatchResult ( processedRequest, response, mappedHandler, mv, dispatchException) ;
}
}
第一章 总结
AbstractApplicationContext.refresh()
=> invokeBeanFactoryPostProcess()
// IOC容器初始化
==> ClasspathBeanDefinitionScan.doScan()
// 查找指定包下的BeanDefinition对象(注解Bean、XML Bean)
===> findCandidateComponents()
// 处理BeanDefinition对象的元数据,包括@Lazy、@Primary、构造函数参数等
===> postProcessBeanDefinition()
// 将BeanDefinition对象注册到DefaultListableBeanFactory的beanDefinitionNames集合
===> registerBeanDefinition()
// 对所有的非Lazy的单例对象初始化
=> finishBeanFactoryInitialization()
// 遍历beanDefinitionNames集合,调用getBean()对所有的BeanDefinition进行初始化
==> DefaultListableBeanFactory.preInstantiateSingletons()
===> AbstractAutowireCapableBeanFactory.createBean()
// 对待初始化的Bean进行前置处理
====> resolveBeforeInstantiation()
// AOP,检查待创建的Bean对象是否满足切入点表达式,若满足则创建代理对象
=====> AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation()
====> doCreateBean()
// 对象实例创建,使用反射constructor.newInstance()
=====> createBeanInstance()
// 处理Bean对象的@PostConstruct、@PreDestroy、@Autowired、@Resource、@Inject等注解
=====> applyMergedBeanDefinitionPostProcessors()
// 查找@PostConstruct、@PreDestroy、@Resource注解,并生成InjectionMetadata对象,
//存入CommonAnnotationBeanPostProcessor.injectionMetadataCache容器中
======> CommonAnnotationBeanPostProcessor.findResourceMetadata()
// 查找@Autowired、@Value、@Inject注解,并生成InjectionMetadata对象,
//存入AutowiredAnnotationBeanPostProcessor.injectionMetadataCache容器中
======> AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata()
// 将主Bean的单例工厂保存到三级缓存DefaultSingletonBeanRegistry.singletonFactories
//(如果需要提前引用主Bean,则调用单例工厂的后置处理器beanPostProcessors)
=====> addSingletonFactory()
// 对象属性填充,对主bean进行属性注入或者setter注入。被注入的Bean可以从三级
//缓存singletonFactories中获取主Bean,并提前对其初始化后放入二级缓存放入earlySingletonObjects,
//然后访问或使用主Bean,这样被注入的Bean也是一个完整的对象,从而解决了循环依赖问题
=====> populateBean()
======> InjectionMetadata.inject()
// 对象初始化
=====> initializeBean()
// 调用当前Bean中所有标注了@PostConstruct的方法
======> CommonAnnotationBeanPostProcessor.invokeInitMethods()
=> finishRefresh()
// 将单例Bean放入一级缓存singletonObjects中,并移除存放提前曝光对象的二级缓存
//earlySingletonObjects和该bean对象的创建工厂缓存singletonFactories
DefaultSingletonBeanRegistry.addSingleton()
第二章 FAQ
spring事务失效的条件? spring事务失效1 spring事务失效2 Spring事务失效的 8 大原因 Spring 如何在一个事务中开启另一个事务? spring事务原理? spring事务原理 spring setter注入与构造函数注入?
setter注入:发生在populateBean阶段,调用applyPropertyValues方法,完成注入; 构造函数注入:发生在createBeanInstance阶段,调用ConstructorResolver.autowireConstructor方法,先为被注入的bean完成初始化,接着调用constructor.newInstance(args)完成主bean的初始化。若产生循环依赖问题,则注入失败,程序报错。