作为java boy不可跨过的一道鸿沟。spring凭借着其强大的社区能力让我们在进行web开发时如鱼得水,spring的众多子嗣中大都基于Spring Framework来提供能力
在Spring官网这样描述Spring道
What We Mean by "Spring"
The term "Spring" means different things in different contexts. It can be used to refer to the Spring Framework project itself, which is where it all started. Over time, other Spring projects have been built on top of the Spring Framework. Most often, when people say "Spring", they mean the entire family of projects. This reference documentation focuses on the foundation: the Spring Framework itself.
Spring这个词在不同的上下文中有不同的含义。 它可以用来指 Spring Framework 项目本身,这就是一切的开始。 随着时间的推移,其他 Spring 项目也建立在 Spring 框架之上。 大多数情况下,当人们说“Spring”时,他们指的是整个项目系列。 本参考文档重点关注基础:Spring 框架本身。
The Spring Framework is divided into modules. Applications can choose which modules they need. At the heart are the modules of the core container, including a configuration model and a dependency injection mechanism. Beyond that, the Spring Framework provides foundational support for different application architectures, including messaging, transactional data and persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in parallel, the Spring WebFlux reactive web framework.
Spring 框架分为多个模块。 应用程序可以选择他们需要的模块。 核心是核心容器的模块,包括配置模型和依赖注入机制。 除此之外,Spring 框架还为不同的应用程序架构提供基础支持,包括消息传递、事务数据和持久性以及 Web。 它还包括基于 Servlet 的 Spring MVC Web 框架,同时还包括 Spring WebFlux 反应式 Web 框架。
在其documentation中,我们可以看到Core
包含了IoC和AOP以及其他Spring特性

Spring Core
This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) principle. Dependency injection (DI) is a specialized form of IoC, whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The IoC container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.
The
org.springframework.beansandorg.springframework.contextpackages are the basis for Spring Framework’s IoC container. The [BeanFactory]interface provides an advanced configuration mechanism capable of managing any type of object. [ApplicationContext]is a sub-interface ofBeanFactory. It adds:
- Easier integration with Spring’s AOP features
- Message resource handling (for use in internationalization)
- Event publication
- Application-layer specific contexts such as the
WebApplicationContextfor use in web applications.In short, the
BeanFactoryprovides the configuration framework and basic functionality, and theApplicationContextadds more enterprise-specific functionality. TheApplicationContextis a complete superset of theBeanFactoryand is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using theBeanFactoryinstead of theApplicationContext
Spring Core的第一个就是IOC容器,所谓的IOC就是Inversion of Control控制反转,就是把bean的一生交给spring来管理,在你需要的时候向容器进行获取,实现IOC的基础就是org.springframework.beans和包org.springframework.context包,其中BeanFactory 接口提供了一种高级配置机制,能够管理任何类型的对象。 ApplicationContext是 BeanFactory的子接口。BeanFactory提供了配置框架和基本功能, ApplicationContext了增加更多特定功能。
怎么知道要取哪些Bean
Several implementations of the
ApplicationContextinterface are part of core Spring. In stand-alone applications, it is common to create an instance ofAnnotationConfigApplicationContextorClassPathXmlApplicationContext.
spring官网给我们提供了个例子,先写个xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
然后在java中这样使用
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();
我们来看看ApplicationContext是怎么构建的
/**
* Create a new ClassPathXmlApplicationContext, loading the definitions
* from the given XML files and automatically refreshing the context.
* @param configLocations array of resource locations
* @throws BeansException if context creation failed
*/
public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
this(configLocations, true, null);
}
/**
* Create a new ClassPathXmlApplicationContext with the given parent,
* loading the definitions from the given XML files.
* @param configLocations array of resource locations
* @param refresh whether to automatically refresh the context,
* loading all bean definitions and creating all singletons.
* Alternatively, call refresh manually after further configuring the context.
* @param parent the parent context
* @throws BeansException if context creation failed
* @see #refresh()
*/
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);//传进来的是null,不会执行
setConfigLocations(configLocations);
if (refresh) {//传进来为true,会执行
refresh();
}
}
接着来看看#setConfigLocations做了什么
/**
* Set the config locations for this application context.
* <p>If not set, the implementation may use a default as appropriate.
*/
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
setConfigLocations看起来并没有做了什么伟大的工程,只是对地址进行了处理,接下来看#refresh做了什么,大概的步骤是
- 初始化上下文
- bean工厂的初始化
- 事件、配置、bean的初始化
@Override
public void refresh() throws BeansException, IllegalStateException {
this.startupShutdownLock.lock();
try {
//标记当前线程为启停线程
this.startupShutdownThread = Thread.currentThread();
//标记refresh开始
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备上下文
prepareRefresh();
//告诉子类刷新内部 bean 工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备bean工厂以便在当前上下文中使用
prepareBeanFactory(beanFactory);
try {
// 对工厂进行默认后置处理
postProcessBeanFactory(beanFactory);
//标记开始bean后置处理
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 使用后置处理器对工厂进行处理
invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean后置处理器
registerBeanPostProcessors(beanFactory);
//标记bean后置处理结束
beanPostProcess.end();
// 初始化此上下文的消息源.
initMessageSource();
// 为此上下文初始化事件广播者
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊bean
onRefresh();
// 检查侦听器bean并注册
registerListeners();
// 实例化所有非懒加载的剩余单例
finishBeanFactoryInitialization(beanFactory);
// 完成刷新
finishRefresh();
}
catch (RuntimeException | Error ex ) {
//异常处理
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//销毁已创建的单例
destroyBeans();
// 重置上下文的激活状态
cancelRefresh(ex);
// 抛出异常
throw ex;
}
finally {
//标记refresh事件结束
contextRefresh.end();
}
}
finally {
//清空线程绑定
this.startupShutdownThread = null;
this.startupShutdownLock.unlock();
}
}
refresh的执行流程如上,我们来一步一步看下来,首先我们来看看prepareRefresh、obtainFreshBeanFactory和prepareBeanFactory这三个步骤做了什么
prepareRefresh
/**
* 准备此上下文以进行刷新,设置其启动日期和活动标志,以及执行属性源的任何初始化
*/
protected void prepareRefresh() {
// 设置启动状态,并输出日志
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 初始化上下文环境中的属性数据源占位符
initPropertySources();
// 属性校验
getEnvironment().validateRequiredProperties();
// 刷新必要的属性参数
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 允许使用的早期事件,在广播器完成初始化后可以发布
this.earlyApplicationEvents = new LinkedHashSet<>();
}
流程是,标记上下文的启动状态->进行属性校验->刷新必要的参数
obtainFreshBeanFactory
/**
* 告诉子类刷新内部 bean 工厂。
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新bean工厂
refreshBeanFactory();
//返回bean工厂
return getBeanFactory();
}
/**
* 此实现对此上下文的底层 Bean 工厂执行实际刷新,关闭以前的 Bean 工厂(如果有)并为上下文生命周期的下一阶段初始化一个新的 Bean 工厂。
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
//先清空当前的bean工厂
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建一个当前上下文的bean工厂
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
beanFactory.setApplicationStartup(getApplicationStartup());
//定制工厂的一些参数
customizeBeanFactory(beanFactory);
//加载BeanDefinition
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
prepareBeanFactory
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
// BeanDefinition配置解析器
AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
// class扫描器
ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);
// 名称生成器
BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
if (beanNameGenerator != null) {
reader.setBeanNameGenerator(beanNameGenerator);
scanner.setBeanNameGenerator(beanNameGenerator);
beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
}
// 作用域解析器
ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
if (scopeMetadataResolver != null) {
reader.setScopeMetadataResolver(scopeMetadataResolver);
scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
// 扫描在注解中声明的Class
if (!this.componentClasses.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("Registering component classes: [" +
StringUtils.collectionToCommaDelimitedString(this.componentClasses) + "]");
}
reader.register(ClassUtils.toClassArray(this.componentClasses));
}
// 扫描basePackage下的类型
if (!this.basePackages.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("Scanning base packages: [" +
StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");
}
scanner.scan(StringUtils.toStringArray(this.basePackages));
}
// 获取配置文件所在路径
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
try {
Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
if (logger.isTraceEnabled()) {
logger.trace("Registering [" + configLocation + "]");
}
reader.register(clazz);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class for config location [" + configLocation +
"] - trying package scan. " + ex);
}
int count = scanner.scan(configLocation);
if (count == 0 && logger.isDebugEnabled()) {
logger.debug("No component classes found for specified class/package [" + configLocation + "]");
}
}
}
}
}
这三个方法的步骤大概是为上下文对象创建bean工厂。
Bean怎么交给spring管理
BeanFactory
基于spring官网对ioc的描述,我们来看看 BeanFactory 是什么?
通过spring的源码,我们可以看到BeanFactory接口提供了这些相关的方法,这些方法都是和bean相关的获取方法,这里没看到put方法,我们来看看为什么没有put的方法,我们通过#getBean(String,Class<T>)的抽象实现类看看
拿到Bean
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//处理bean名称,主要的去除bean工厂的前缀和转换别名
String beanName = transformedBeanName(name);
Object beanInstance;
// 从缓存中获取单例对象 by beanName 这里用到的三级缓存
Object sharedInstance = getSingleton(beanName);
//如果获取到了实例,则从bean中获取实例
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//没取到实例,则自己建
//原型模式下当前线程也正在构建这个bean(循环依赖),则抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 如果存在parentBeanFactory,并且没有当前bean的定义,则从parentBeanFactory中获取实例
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory abf) {
return abf.doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//如果不需要进行类型检查,则将bean标记为构建中(写进alreadyCreated缓存中)
if (!typeCheckOnly) {markBeanAsCreated(beanName);}
//标记StartupStep,用于时间计算
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
//通过beanName拿到合并后的BeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//校验RootBeanDefinition,如果是Abstract则抛出异常
checkMergedBeanDefinition(mbd, beanName, args);
// 获取当前bean的依赖,并进行判断,确保所有的依赖都装在完成
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
//遍历所有依赖
for (String dep : dependsOn) {
//判断当前bean是否被dep依赖了(循环依赖)
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册依赖关系,key=dep,value=beanName,dependentBeanMap[类型ConcurrentHashMap]
registerDependentBean(dep, beanName);
//创建dep实例
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
catch (BeanCreationException ex) {
if (requiredType != null) {
// Wrap exception with current bean metadata but only if specifically
// requested (indicated by required type), not for depends-on cascades.
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Failed to initialize dependency '" + ex.getBeanName() + "' of " +
requiredType.getSimpleName() + " bean '" + beanName + "': " +
ex.getMessage(), ex);
}
throw ex;
}
}
}
// 构建实例
if (mbd.isSingleton()) {
//单例模式,构建这个bena,并放到单例池
sharedInstance = getSingleton(beanName, () -> {
//实现的getObject()方法
try {
//构建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//出现异常就销毁当前bean
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//原型模式,构建一个新的实例
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
if (!isCacheBeanMetadata()) {
clearMergedBeanDefinition(beanName);
}
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
从源码中可以看出:会先从缓存中通过byBeanName的方式使用#getSingleton获取bean,getSingleton从三级缓存中获取bean的源码如下:
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//尝试从singletonObjects(一级缓存)中获取bean
Object singletonObject = this.singletonObjects.get(beanName);
//如果一级缓存没有这个bean,并且这个bean在构建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//尝试从earlySingletonObjects(二级缓存)中获取bean
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存拿不到且允许从放入二级缓存
if (singletonObject == null && allowEarlyReference) {
//lock 单例池
synchronized (this.singletonObjects) {
//重新尝试从一二级缓存中获取一次实例,如果实例还是空,则使用三级缓存来构建这个bean,并放入到二级缓存中
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
如果上面这一步拿到了bean就直接进行返回,如果拿到的是factoryBean则通过该factory构建bean并返回,如果这一步没拿到bean则会自己构建,我们以单例模式往下看,他会走DefaultSingletonBeanRegistry类的#getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//串行操作bean池
synchronized (this.singletonObjects) {
//尝试从bean池中获取bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//渠道的bean是null,则判断bean是否被销毁,如是则抛出异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//执行创建单例对象前的回调,即判断bean没被排除并且能放进去记录正在构建的bean的map中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//从传进来的单例工厂获取bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//执行创建bean的后置回调,即从创建中的map移除
afterSingletonCreation(beanName);
}
//如果是新建的单例对象,就将单例对象塞进去单例对象池,key beanName value object
// 从 三级缓存(singletonFactories)、二级缓存(earlySingletonObjects)移除beanName
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
构建Bean
这里会去调用ObjectFactory实现类的#getObject方法,源码中传入一个函数调用AbstractBeanFactory的#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 确保此时 bean 类确实已被解析,并且在动态解析的类无法存储在共享合并 bean 定义中的情况下克隆 bean 定义。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
}
try {
// 如果applyBeanPostProcessorsBeforeInstantiation返回了一个bean,则不会走createBean流程,直接将bean返回
// 这里为什么这么做,可以看AbstractAutoProxyCreator#postProcessBeforeInstantiation的处理,用于处理AOP代理对象的<例子>,SpringBoot AutoConfig处理JDBC连接的DataSourceInitializerPostProcessor也可以
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//执行构造bean的方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
具体在构建Bean的逻辑是在#doCreateBean方法中
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 开始实例化
BeanWrapper instanceWrapper = null;
//如果是单例的,在在构建的时候,将beanName从factoryBeanInstanceCache中移除并取得这个wrapper
//在#getSingletonFactoryBeanForTypeCheck执行完成拿到FactoryBean后put进去的
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//如果factoryBeanInstanceCache中没取到,则构建一个
if (instanceWrapper == null) {
//这里具体的就是 1. 如果存在Supplier回调,则通过Supplier回调构建实例 elese
//2.通过Bean 工厂实例化 else 3.通过构造函数实例化 else 4.通过默认的无参构造函数实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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.markAsPostProcessed();
}
}
// 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 {
//为bean注入属性
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
throw bce;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), 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,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
总结
- IoC Container就是个Map,key为BeanName,value为管理的bean对象
- 获取bean的时候,会先从一级缓存获取Bean,如果获取到了直接返回
- 如果一级缓存没有,则判断bean是否在构建,从早期缓存(二级缓存)中获取,如果二级缓存中也没有,则判断是否支持早期引用,是的话从三级缓存中查找bean的早期引用,得到这个
早期引用后put进二级缓存,并且删除三级缓存
AOP
从上面的内容,我们已经知道了bean是怎么托管给spring管理了,那既然Spring已经接管了bean,那理所当然可以对bean进行强化,也就是我们所谓的AOP
我从spring官网对AOP的定义摘录了这些解释:
AOP proxy: An object created by the AOP framework in order to implement the aspect contracts (advice method executions and so on). In the Spring Framework, an AOP proxy is a JDK dynamic proxy or a CGLIB proxy.
Spring AOP includes the following types of advice:
Before advice: Advice that runs before a join point but that does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception).
After returning advice: Advice to be run after a join point completes normally (for example, if a method returns without throwing an exception).
After throwing advice: Advice to be run if a method exits by throwing an exception.
After (finally) advice: Advice to be run regardless of the means by which a join point exits (normal or exceptional return).
Around advice: Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.
内容总结一下大概就是:
- AOP是代理了bean,不同事件通知不同的执行方法
- 包含了这些事件节点: Before、After returning、After throwing、After (finally)、Around,也就是我们所谓的
切点
知道了AOP的内容,我们来看看Spring源码中是怎么执行处理的,从spring官网中,给我们启用@AspectJ支持的Guide如下;
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy />
</beans>
可以看到AspectJAutoProxyBeanDefinitionParser实现了BeanDefinitionParser并且重写了parse方法,主要的逻辑是调用了AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
这个方法的流程是:创建和注册AOP标签解析器和aop:include相关的标签,这里知道了@Aspect注解怎么解释了,接着来看看怎么增强bean的
前面注册BeanDefinition的时候实际是注册了个AnnotationAwareAspectJAutoProxyCreator
这个类继承实现了BeanPostProcessor接口,主要的逻辑在AbstractAutoProxyCreator#postProcessAfterInitialization
/**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
@Nullable
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyBeanReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
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;
}
这里我们可以看到和ioc的内容差不多,重点在getAdvicesAndAdvisorsForBean这个方法,去获取适合当前bean的增强器(Advices)
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
/**
* Find all eligible Advisors for auto-proxying this class.
* @param beanClass the clazz to find advisors for
* @param beanName the name of the currently proxied bean
* @return the empty List, not {@code null},
* if there are no pointcuts or interceptors
* @see #findCandidateAdvisors
* @see #sortAdvisors
* @see #extendAdvisors
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
try {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
catch (BeanCreationException ex) {
throw new AopConfigException("Advisor sorting failed with unexpected bean creation, probably due " +
"to custom use of the Ordered interface. Consider using the @Order annotation instead.", ex);
}
}
return eligibleAdvisors;
}
概括一下这个流程就是:
- 获取bean极核
- 过滤没被@Aspect注解和被过滤规则过滤的bean
- 获取bean的增强方法,根据切点生成对应的增强器
- 缓存增强器,避免重复生成 执行完成后,会执行createProxy方法
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
return buildProxy(beanClass, beanName, specificInterceptors, targetSource, false);
}
private Object buildProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource, boolean classOnly) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory clbf) {
AutoProxyUtils.exposeTargetClass(clbf, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader smartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = smartClassLoader.getOriginalClassLoader();
}
return (classOnly ? proxyFactory.getProxyClass(classLoader) : proxyFactory.getProxy(classLoader));
}
这个代码的执行流程是:
- 实例化代理工厂
- 判断代理方式
- 把拦截器封装成Advisor对象,add到代理工厂对象中
- 为工厂对象创建代理类
AOP 总结
AOP本质上是基于IOC的Bean代理操作,整体的流程可以概括为:
- 从上下文容器中获取所有的切面定义
- 筛选出当前要代理的bean的切面增强器集合
- 通过增强器集合去生成代理bean