1.建一个测试model
在源码项目里新建一个model,源码编译参考上一篇
建完model后在java包下添加三个类,执行成功就可以了就可以开始进行源码阅读了
这里提一下还有一个ClassPathXmlApplicationContext,这个就是通过上下文去初始化Spring环境
public class Test {
public static void main(String[] args) {
//注解去初始化Spring环境
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MyAppConfig.class);
System.out.println(applicationContext.getBean(CityService.class));
}
}
@Configuration
@ComponentScan("com.demo.spring")
public class MyAppConfig {
}
@Component
public class CityService {
}
Bean的生命周期
首先我们使用IDEA点进去看一下AnnotationConfigApplicationContext,这个就是通过注解来配置Spring的上下文环境
//载入解析注册的过程
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//父类构造函数里,创建了一个Bean工厂
// this.beanFactory = new DefaultListableBeanFactory()
this();
//读取和扫描器,将BeanDefinition方到Map里
register(annotatedClasses);
refresh();
}
1.首先是this方法,this方法干了一个什么事情呢?
首先这个无参构造方法里面呢
public AnnotationConfigApplicationContext() {
//创建一个读取Bean定义的处理器,BeanDefinition
this.reader = new AnnotatedBeanDefinitionReader(this);
//扫描类转换成BD
//仅仅为了程序员去使用AnnotationConfigApplicationContext
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
调用子类构造方法也会调用父类构造方法
public GenericApplicationContext() {
//实例化一个工厂
this.beanFactory = new DefaultListableBeanFactory();
}
Spring工厂:
理论:产生Bean
如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)
如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
2.之后是register(annotatedClasses);方法他做了什么呢
将传入的appConfig.class变成BeanDefinition
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//根据指定的Bean创建一个AnnotatedGenericBeanDefinition
//这个AnnotatedGenericBeanDefinition可以理解为一个数据结构
//包含了类的其他信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//判断这个类是否要跳过解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//得到类的作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//类的作用域添加到数据结构的结构当中
abd.setScope(scopeMetadata.getScopeName());
//生产Bean的名字
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//如果想容器注册注解定义时,使用了额外的限定符注解则解析
//qualifiers是包含了注解数组
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
//加Primary设为首选
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//也是一个数据结构
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//就是把definitionHolder一个DefaultListableFactory,registry就是ApplicationContext
//点进代码看到map.put
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
3.最后是refresh();这个是SpringFramework里一个主要的代码说是最主要也不为过。这里呢一共调用了12个方法
@Override
public void refresh() throws BeansException, IllegalStateException {
//同步的方法
synchronized (this.startupShutdownMonitor) {
// 1.Prepare this context for refreshing.
prepareRefresh();
// 2.Tell the subclass to refresh the internal bean factory.
// 刷新beanFactory,删除旧的beanFactory,创建新的beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3.Prepare the bean factory for use in this context.
//准备bean工厂以供在此上下文中使用。
prepareBeanFactory(beanFactory);
try {
// 4.Allows post-processing of the bean factory in context subclasses.
//允许在上下文子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
// 5.Invoke factory processors registered as beans in the context.
// 调用工厂处理器,解析类信息 生成Bean
// 执行自定义的processBean ,扫描Bean 处理了import
// 扫描->putMap(RootBeanDefinition)->(1.custom)
// 程序员可以,先处理自定义的,先处理order的
invokeBeanFactoryPostProcessors(beanFactory);
// 6Register bean processors that intercept bean creation.
//注册BeanPostProcessor前后
registerBeanPostProcessors(beanFactory);
// 7Initialize message source for this context.
initMessageSource();
// 8Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 9Initialize other special beans in specific context subclasses.
onRefresh();
// 10Check for listener beans and register them.
registerListeners();
// 11Instantiate 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();
//启动事件标识位
// 设置环境变量和容器的开关标志
(2)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//要对工厂进行初始化
(3)准备工厂
(4)postProcessBeanFactory(beanFactory);
//允许在上下文子类中对bean工厂进行后处理。
(5)invokeBeanFactoryPostProcessors(beanFactory);
1.扫描了符合要求的class文件,各种Import注解
2.解析成BeanDefinition
ps:之前的register也是扫描 但是放入了appConfig.class 也就是AnnotationConfigApplicationContext传入的配置类
3.put->BeanDefinitionMap->调用自定义的BeanFactoryPostProcesser,还有内置的。
/**
* 扩展原理:
* BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
*
* 1、BeanFactoryPostProcessor:beanFactory的后置处理器;
* 在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
* 所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
*
*
* BeanFactoryPostProcessor原理:
* 1)、ioc容器创建对象
* 2)、invokeBeanFactoryPostProcessors(beanFactory);
* 如何找到所有的BeanFactoryPostProcessor并执行他们的方法;
* 1)、直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
* 2)、在初始化创建其他组件前面执行
*
* 2、BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
* postProcessBeanDefinitionRegistry();
* 在所有bean定义信息将要被加载,bean实例还未创建的时候;
* 优先于BeanFactoryPostProcessor执行;
* 利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件;
*
* 原理:
* 1)、ioc创建对象
* 2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
* 3)、从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。
* 1、依次触发所有的postProcessBeanDefinitionRegistry()方法
* 2、再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
*
* 4)、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法
*
(11)finishBeanFactoryInitialization(beanFactory);
实例化也就是new
beanFactory.preInstantiateSingletons();
//log级别
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
//所有Bean的名字
// 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<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
//触发所有非懒加载的单例Beans
for (String beanName : beanNames) {
//bdmap.get
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
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放到单例池里 单例池是一个ConcuretHashMap
getBean(beanName);
}
}
}
// 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();
}
}
}