灌水
spring 用了很长时间了,譬如 IOC、DI、AOP之类高端大气上档次的专业名词是如雷贯耳,真是可远观而不可亵玩。
如今工作一年了,是时候解开她神秘的面纱,开始攻城略地!
先写段入口代码
/**
* ApplicationContext的作用 :
* 1.用于访问应用程序组件的Bean工厂方法
* 2.以通用方式加载文件资源的能力。
* 3.能够向注册的监听器发布事件。
* 4.解决消息的能力,支持国际化。
*/
@Test
public void test() {
//通过ClassPathXmlApplicationContext加载我们配置的xml文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User bean = (User) context.getBean("a", User.class);
System.out.println(bean.toString());
}
运行程序,进入ClassPathXmlApplicationContext
/**
* String [] configLocations 这里面是我们要加载的xml文件
* boolean refresh 是否自动刷新上下文,加载所有bean定义并创建所有单例。
* 或者,在进一步配置上下文之后手动调用refresh。
*/
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
// 这一步是将我们的配置文件加载进ApplicationContext 中。
setConfigLocations(configLocations);
if (refresh) {
//关键部位:更新操作
refresh();
}
}
进入refresh()方法
开始碰触IOC核心。
- ClassPathXmlApplicationContext 调用父类的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.
// 这里面就是 获取 IOC bean 工厂。 下面重点看这块。
// ----> 根据断点追总结果,将解析的xml文件得到的Bean定义对象保存到MAP 中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 设置容器标准特征,添加了一些后置处理器
// 将beanPostProcessor注册监听;
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.
// 将 BeanPOstProcessor注册给BeanFactory
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.
//做了三件事情
//1. Bean 的实例化
//2. 属性注入
//3.执行后置处理器的一些初始化方法
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();
}
}
}
解读prepareRefresh()
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
//设置上下文启动时间
this.startupDate = System.currentTimeMillis();
//下面两个set是context设置存活标志。
this.closed.set(false);
this.active.set(true);
//打印日志,不用管
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
//这里是处理xml文件中的占位符初始化。比如我们数据库中一些参数配置在properties文件中,在系统加载时会将参数值填充进去。
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
//检查运行环境
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
解读 obtainFreshBeanFactory();
流程:
- 获取bean容器
- 设置是否可以重写Bean
- 设置是否可以循环依赖
- 创建Xml Bean定义的解析器设置到beanFactory
- 解析xml,放入beanDefintionMap
- 设置序列号
/**
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 这个方法主要获取这个更新context 潜在的bean工厂,如果之前存在就销毁beans实例、关闭bean工厂,{ destroyBeans(); closeBeanFactory();} & 在下面继续贴这个方法的解析!
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
分析 refreshBeanFactory()
protected final void refreshBeanFactory() throws BeansException {
//如果存在beanfactory 执行销毁
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 这里获取默认的bean 容器! 这个就是我们要寻找的IOC容器...是孕育我们整个项目Bean的伊甸园!
// return new DefaultListableBeanFactory(getInternalParentBeanFactory());
DefaultListableBeanFactory beanFactory = createBeanFactory();
//给beanfactory设置序列化ID,后面有需要的话可以通过序列化ID,实例一个beanFactory
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//Loads the bean definitions via an XmlBeanDefinitionReader.
//通过XmlBeanDefinitionReader 加载 bean 定义。(BeanDefinition:相当于人 的一个身份证)
//initBeanDefinitionReader(beanDefinitionReader); 这个东西初始化beanDefinition阅读器
//loadBeanDefinitions(beanDefinitionReader);使用给定的XmlBeanDefinitionReader加载bean定义
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
--------------- 略-----------------
}
分析 loadBeanDefinitions(beanFactory);
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
--------------- 略-----------------
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//由此加载beanDefinitions
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
--------------- 略-----------------
============= 进入doLoadBeanDefinitions =============
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//加载xml配置文件的DOM树
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
--------------- 略-----------------
============= 进入registerBeanDefinitions =============
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 获取注册之前的beanDefinitions;
int countBefore = getRegistry().getBeanDefinitionCount();
// 注册beanDefinnitions
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
|
|
V
// preProcessXml(root); 前处理器 这个东西啥也没有干。
// parseBeanDefinitions(root, this.delegate); // bean文件解析的主要部分。
|
|
V
// parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {\
--------------- 略-----------------
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//处理默认的节点标签(import、alias、bean)
parseDefaultElement(ele, delegate);
|
|
V
// protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//bean 对象定义
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
|
|
V
registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
// Still in startup registration phase
//到这里beanFactory就彻底创建完毕
//beanDefinitionMap 存放了所有的eanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
// 存放每一个注册的Bean名称
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
}
//
}
else {
// 处理有命名空间的Bean
delegate.parseCustomElement(ele);
}
}
--------------- 略-----------------
}
// postProcessXml(root); 后处理器
// 再一次获取已经注册的bean数量 --- 内置的Bean+应用bean
return getRegistry().getBeanDefinitionCount() - countBefore;
}
解读prepareBeanFactory
主要工作是添加一些后置处理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置 BeanFactory 的类加载器 为当前ApplicationContext的类加载器。
//用于后面反射获取bean对象。
beanFactory.setBeanClassLoader(getClassLoader());
// 设置Bean 表达是解析器。
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 设置后置处理器(可以自己实现)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//自定义的Bean对象在实现这些接口时是没有意义的,容器在自动装配时会自动忽略。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 可以自定义实现接口,BeanPostProcess 来实现自己的后置或者前置处理器注册监听
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
----------------- 略 ----------------
}
解读 finishBeanFactoryInitialization
执行流程:
- 实例化对象
- 属性注入
- 实现 aware 接口对象的回调
- BeanFactoryProcessor对象的before回调
- init-method
- InitializingBean 接口的回调
- BeanFactoryProcessor对象的after回调
- context 销毁对象
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 此处是处理循化依赖
// A对象依赖B,同时B也依赖A
//1. 在A 完成实例化需要注入B对象
//2. 发现B对象不存在容器重
//3. 在实例化B对象
//4. B对象实例完成后,需要注入A对象
//5. 此时容器中已经存在A 对象,直接注入
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 这里开始预初始化singleton beans ,在这个时候不希望在出现bean的定义解析、注册,所以冻结配置
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
//开始实例化Bean对象。
beanFactory.preInstantiateSingletons();
}
分析 preInstantiateSingletons 实例化单例bean (DI )
@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.
//这个是拿到我们所有的Bean名称 在前面创建bean工厂时存放在list中 this.beanDefinitionNames.add(beanName);
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 出发初始化所有非懒加载的单例对象
for (String beanName : beanNames) {
//获取bean定义对象
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// factoryBean : 可以看到bean创建的全过程;(自己实例化的对象并且加到beanfactory容器中。特点是:bean创建过程透明)
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 重点 : 对于普通的Bean,只要调用 getBean(beanName)就可以初始化
getBean(beanName);
------------------------- 调用链start ---------------------------------
|
| 调用doGetBean()
V
//调用
doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//检查对象是否创建
Object sharedInstance = getSingleton(beanName);
// 检查bean定义是否在BeanFactory中
if (parentBeanFactory != null && !containsBeanDefinition(beanName))
// 检查 标记Bean创建
if (!typeCheckOnly) markBeanAsCreated(beanName);
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//先初始化依赖的Bean
// 注意: 这里的依赖指的是depends-on 中定义的依赖
String[] dependsOn = mbd.getDependsOn();
// 创建单例对象
if (mbd.isSingleton());
return createBean(beanName, mbd, args);
| |
| | 调用 createBean() 开始创建bean
V V
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
//准备方法覆盖 (可以对我们的方法进行增强代理)
mbdToUse.prepareMethodOverrides();
//重头戏
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
| | |
| | | 调用 doCreateBean() 开始创建bean
V V V
// 单例模式 ,移除内存中缓存的单例对象
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
// 创建对象的包装对象实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 得到对象实例
final Object bean = instanceWrapper.getWrappedInstance()
...
// 这一步也很关键,前面都是对象的实例化,这一步负责属性的装配(DI)
populateBean(beanName, mbd, instanceWrapper);
------------------------------DI START---------------------------------------
自动装配是在什么时候进行的?
自动装配是属性注入的一种。所以自动装配是在属性注入的时候进行。而属性注入是在我们对象实例化之后进行。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
// 实例的所有属性都在这
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
// 按照名称装配
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 按照类型装配
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
------------------------------DI END---------------------------------------
} -------end ------
//创建多例对象
else if (mbd.isPrototype())
}
------------------------- 调用链end ---------------------------------
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
小节
Spring 提供了两个后之处理器处理回调监听接口 : BeanPostProcessor;Aware 都是顶级接口。可以用来实现我们的特殊需求。
简述: spring ApplicationContext 流程;