功能架构
spring采用的是分层架构
基础模块为Core Container,这个是spring的基石,其它模块都是在此基础上扩展而来。
1. Test模块
- 支持使用JUnit框架测试
2. Core Container模块
- Beans:提供
BeanFactory
接口,提供访问Bean容器方法 - Core:框架的基本组成部分,包括IoC、DI
- Context:应用程序上下文,
ApplicationContext
接口提供配置信息 - SpEL:Spring表达式语言,是一种强大的表达式语言,支持在运行时查询和操作对象图
3. AOP、Aspects、Instrumentation、Messaging
- AOP:面向切面编程,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。实现方式:jdk、cglib
- Aspects:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架
- Instrumentation:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用
- Messaging:消息传递,比如STOMP Messaging
4. Web模块
- 支持WebSocket、Servlet
5. Data Access模块
- Transactions:支持编程和声明式事务管理
- JMS:支持集成Java消息服务,功能为信息的生产和消费
- OXM:支持对象和XML映射,如 JAXB、Castor、XMLBeans、JiBX 和 XStream
- JDBC:支持集成JDBC,大幅度减少了在开发过程中对数据库操作的编码
- ORM:支持集成ORM框架,比如JPA、Hibernate和MyBatis
启动流程
重点关注四个接口:
- BeanDefinitionReader
- BeanDefinition
- BeanFactoryPostProcessor
- BeanFactory
spring启动流程的核心代码是AbstractApplicationContext#refresh()
方法(spring5.2.1)
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 设置启动时间,容器状态,和property sources等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 创建beanFactory
// 内部通过XmlBeanDefinitionReader,加载bean definition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备beanFactory使用前的各种配置,比如上下文类加载器,后置处理器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 默认是空实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化MessageSource,辅助i18n
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.
// 实例化所有的单例bean(非懒加载)
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发送相应事件给监听器
finishRefresh();
}
catch (BeansException ex) {
...
}
finally {
...
}
}
}
BeanFactory和FactoryBean
BeanFactory
- spring容器,实现类有
ClassPathXmlApplicationContext
、AnnotationConfigApplicationContext
FactoryBean
- 在spring容器中有两种Bean,一种是普通的Bean,另一种是FactoryBean
- 根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,在id前面加一个&符号来获取
- 使用场景:在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,比如:SqlSessionFactoryBean
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
代码位置:AbstractBeanFactory#getObjectForBeanInstance()
/**
* Get the object for the given bean instance, either the bean
* instance itself or its created object in case of a FactoryBean.
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 从FactoryBean中获取getObject()返回的对象
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
Bean生命周期
创建bean的代码位置
AbstractAutowireCapableBeanFactory#doCreateBean()
(spring5.2.1)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 实例化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充属性,循环依赖也在这里解决
populateBean(beanName, mbd, instanceWrapper);
// 调用aware和beanPostProcessor
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "省略...");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
调用aware的代码位置
AbstractAutowireCapableBeanFactory#invokeAwareMethods()
setBeanName、setBeanFactoryApplicationContextAwareProcessor#invokeAwareInterfaces()
setApplicationContext
Bean创建循环依赖问题
构造函数的循环依赖无法解决
spring为了解决单例的循环依赖问题,使用了三级缓存
三级缓存在类DefaultSingletonBeanRegistry
中
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
一级缓存singletonObjects
:可以直接使用的完整对象;
二级缓存earlySingletonObjects
:完成实例化而未初始化的对象;
三级缓存singletonFactories
:lambda表达式
场景:A依赖B,B依赖A
- 先实例化A,将A的半成品(其实是lambda函数ObjectFactory)放到三级缓存singletonFactories中
AbstractAutowireCapableBeanFactory#doCreateBean()
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); - 给半成品A填充属性B时,发现B还未实例化,就会先去实例化B
- 在实例化B后,也将B的半成品(lambda函数ObjectFactory)放到三级缓存
- 给半成品B填充属性A,这时候能够从三级缓存中拿到半成品A
DefaultSingletonBeanRegistry#getSingleton()
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) {
// 二级缓存没有,则从三级缓存拿
// 三级缓存拿到bean后,将bean放入到二级缓存, 并从三级缓存中删除,
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
- 拿到半成品A的lambda函数ObjectFactory后,调用ObjectFactory.getObject()方法最终会调用getEarlyBeanReference()方法,getEarlyBeanReference这个方法主要逻辑是如果bean被AOP切面代理则返回的是proxy对象,如果未被代理则返回的是原bean实例。
- 此时B注入的是一个半成品A,不过随着B初始化完成后,A会继续进行后续的初始化操作,最终B会注入的是一个完整的A实例。
- 最后,将B、A实例添加到一级缓存
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
通过上述流程分析,发现二级缓存好像没什么用。
其实不然,代码singletonObject = singletonFactory.getObject()
是从三级缓存中获取bean对象,如果获取的是代理对象,每次返回的代理对象实例不是同一个,不满足单例要求,加上二级缓存存放代理对象可以避免这个问题。
通过上下文获取单例Bean,是从一级缓存
singletonObjects
获取
Person person = (Person) applicationContext.getBean(“person”);
AOP
AOP(Aspect-Oriented-Programming,面向切面编程)
动态代理两种实现方式
- JDK动态代理:原对象有接口
- CGLIB动态代理:原对象没有接口
spring代理实际上是对JDK代理和CGLIB代理做了一层封装,类图如下:
创建代理对象代码位置:AbstractAutoProxyCreator#wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
- spring aop严格的来说使用的是动态代理,所以实际上spring代理和AspectJ的关系并不大
- spring aop封装了jdk和cglib的动态代理实现,同时引入了AspectJ的编程方式和注解。这样不仅可以使用标准的AOP编程规范来编写代码,还可以使用AspectJ方式
AOP相关概念
通知(Advice) 包含了需要用于多个应用对象的横切行为,通俗一点说就是定义了“什么时候”和“做什么”。
连接点(Join Point) 是程序执行过程中能够应用通知的所有点
切点(Poincut) 是定义了在“什么地方”进行切入,哪些连接点会得到通知。显然,切点一定是连接点
切面(Aspect) 是通知和切点的结合。通知和切点共同定义了切面的全部内容
引入(Introduction) 允许我们向现有的类中添加新方法或者属性。
织入(Weaving) 是把切面应用到目标对象并创建新的代理对象的过程,分为编译期织入、类加载期织入和运行期织入