目录
前言
概述
Bean生命周期
BeanFactory与FactoryBean
循环依赖
事务
Springboot核心思想
最近通过看b站培训机构的Spring和SpringBoot源码教程视频学习Spring&SpringBoot的原理和思想,视频是以源码讲解的方式演示,这里分享一些关键点的笔记。
Spring的核心思想是IOC和AOP,IOC是控制反转,是将程序中需要用到的对象创建过程交给容器实现,让容器根据xml的配置实现对对象的创建和依赖注入。AOP是面向切面编程,是对一系列纵向请求做横向的拦截处理,Spring里面使用到AOP的地方主要是BeanFactoryPostProcessor和BeanPostProcessor增强器和Aspect切面。
视频里整理了一个说明Bean生命周期的图:
如上图,bean的定义信息由一开始在xml等配置文件中表示,通过beandefinitionreader加载到一开始关联的beanfactory中,beanfactory是bean的工厂类最顶层接口,以懒加载的方式创建bean,而它的子类ApplicationContext实例化的时候就创建好了bean对象。bean的创建过程大概如下:
1、实例化bean,即开辟空间存放对象;
2、populatebean,填充属性;当 Bean 本身实现了 BeanNameAware 接口,这个时候会根据接口方法,来设置 Bean 的 name;
3、当 Bean 本身实现了 BeanFactoryAware 接口,这个时候会根据接口方法,将 BeanFactory 设置给 Bean;
4、当 Bean 本身实现了 ApplicationContextAware 接口,这个时候 Bean会将获取到ApplicationContext 对象;
5、当 Bean 本身实现了 BeanPostProcessor 接口时,则执行程序中的前置处理方法;
6、当 Bean 本身实现了 InitializingBean 接口时,这个时候还会执行 afterPropertiesSet 方法,进行配置的一个加载;
7、就是执行自身的 init 方法,进行 Bean 的初始化;
8、执行 BeanPostProcessor 中的后置处理方法,即创建完成;
9、被程序使用和最终销毁。
关于bean的生命周期,网上还有一个图可以说明:
不过这里少了bean实现几个内置接口的过程。
Beanfactory作为bean对象的工厂,属于Spring容器相关体系的根结点接口,作为获取bean完整对象的入口。BeanFactory保存从配置文件中读取到的BeanDefinition信息存在beanDefinitionMap中:
private final Map beanDefinitionMap;
默认的BeanFactory实现类:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Nullable
private static Class> javaxInjectProviderClass;
private static final Map> serializableFactories;
@Nullable
private String serializationId;
private boolean allowBeanDefinitionOverriding = true;
private boolean allowEagerClassLoading = true;
@Nullable
private Comparator
先创建Bean(doCreateBean),再填充bean属性(populateBean):
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
FactoryBean自定义类的生产方式,生产特殊的bean。具有its signalinstance的方法和getobject的方法。在bean的创建过程中,会判断如果bean实现了FactoryBean的接口,则会调用它的getobject方法实例化对象。
public interface FactoryBean {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class> getObjectType();
default boolean isSingleton() {
return true;
}
}
Spring在创建bean对象过程中可能会有循环依赖的问题,也就是两个或者多个bean对象相互作为属性形成了循环依赖。Spring为解决循环依赖使用了三级缓存。其中,一级缓存存放的完整的bean,二级缓存存放的实例化但不完整而且被其他正在创建的bean设置为属性的的bean,三级缓存存放是还没实例化的bean,以一个lambda表达式表示,也是一个匿名对象,内部有一个getObject方法负责生产bean对象,当被调用的时候有两种情况,一种是生产出普通对象,一种是生产bean的动态代理对象,使用三级缓存保证了生产bean过程的唯一性。
三级缓存对象在类DefaultSingletonBeanRegistry中:
private final Map singletonObjects = new ConcurrentHashMap(256); // 一级缓存
private final Map> singletonFactories = new HashMap(16);//三级缓存
private final Map earlySingletonObjects = new ConcurrentHashMap(16);//二级缓存
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized(this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
从上面代码看出,获取对象(getSingleton)的时候首先从一级缓存中尝试获取,如果结果为空,则从二级缓存中获取,如果结果再为空,则从三级缓存中获取singletonFactory对象并调用getObject方法创建对象,然后将结果放到二级缓存,删除三级缓存。
Spring事务的两种表示形式,一种是通过注解,也就是是使用transaction注解进行标注,另一种是通过配置文件的方式,也就是在xml配置文件中配置transaction manager以及通知和事务切点。
1、约定大于配置,约定项目目录结构;
2、提供内置tomcat,方便打jar包编译和部署;
3、自动配置集成第三方组件框架,如集成kafka、mybatis等;
4、提供web starter起步依赖,简化配置;