Spring源码解读


第一章 Spring源码解读

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.0.RELEASE</version>
</parent>
  1. spring容器与web容器:
  • spring容器:org.springframework.context.ApplicationContext;
  • web容器:javax.servlet.ServletContext(org.apache.catalina.core.ApplicationContext implements ServletContext)。
  1. 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 {
   	// 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();
   }
   
   protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   	// beanFactory ⇒ DefaultListableBeanFactory 
   	beanFactory.preInstantiateSingletons();
   }

}
  1. 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;
	}
}
  1. 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);
			// Trigger initialization of all non-lazy singleton beans...
			for (String beanName : beanNames) {
				RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
				if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
					getBean(beanName);
				}
			}
		}
}
  1. 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 {
		// 第一步:实例化bean
		instanceWrapper = createBeanInstance(beanName, mbd, args);
		// 为Bean对象绑定后置处理器
		applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
		// 为避免后期循环依赖,提前曝露ObjectFactory到第三级缓存中。
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        // 第二步:填充属性
		populateBean(beanName, mbd, instanceWrapper);
		// 第三步:执行初始化逻辑
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/** Cache of singleton objects: bean name --> bean instance,已经完成初始化的对象(一级缓存) */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
	/** Cache of early singleton objects: bean name --> bean instance,提前曝光的对象(二级缓存) */
	private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
	/** Cache of singleton factories: bean name --> ObjectFactory,提前曝光对象的后置处理器,当对象被提前曝光且被提前引用时才触发后置处理器(三级缓存)  */
	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);
	}
}
  1. @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()。
  1. @Autowired、@Value和@Inject注解的实现:
  • 同上,不过是在populateBean阶段,调用postProcessProperties方法,然后调用AutowiredAnnotationBeanPostProcessor.postProcessProperties()完成InjectionMetadata对象的封装,然后放入injectionMetadataCache缓存
  • @Resource优先byName,@Autowired和@Inject优先byName。
  1. 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);
			});
		}
	}
}
  1. 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

  1. spring事务失效的条件?
    spring事务失效1
    spring事务失效2
    Spring事务失效的 8 大原因
    Spring 如何在一个事务中开启另一个事务?
  2. spring事务原理?
    spring事务原理
  3. spring setter注入与构造函数注入?
  • setter注入:发生在populateBean阶段,调用applyPropertyValues方法,完成注入;
  • 构造函数注入:发生在createBeanInstance阶段,调用ConstructorResolver.autowireConstructor方法,先为被注入的bean完成初始化,接着调用constructor.newInstance(args)完成主bean的初始化。若产生循环依赖问题,则注入失败,程序报错。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值