接着 我们正式开始学习获取 bean 实例方法,该方法是Spring 最核心的方法
,也是最难的方法,我们首先不能扣太多的细节,先从一个比较简单的实例化的依赖注入入手。
@Override
public Object getBean(String name) throws BeansException {
// 获取name对应的bean实例,如果不存在,则创建一个
return doGetBean(name, null, null, false);
}
doGetBean 方法详解。
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1.解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
String beanName = transformedBeanName(name);
Object bean;
// 2.从Spring的三级缓存中获取bean,解决循环依赖的主要的思想
// 当A依赖B,B返回来也依赖A的时候,这个时候获取到的A就是从Spring的第三级缓存中获取到
Object sharedInstance = getSingleton(beanName);
// 6.如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 7.根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 8.1 遍历当前bean依赖的bean名称集合
for (String dep : dependsOn) {
// 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
if (isDependent(beanName, dep)) {
// 8.3 如果是循环依赖则抛异常
throw new BeanCreationException("Circular depends-on relationship between '" );}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.创建bean实例
// scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// ****调用createBean创建Bean实例****
return createBean(beanName, mbd, args);
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
// 10.检查所需类型是否与实际的bean对象的类型匹配
if (requiredType != null && !requiredType.isInstance(bean)) {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
return (T) bean;
}
createBean方法总体流程
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 1.解析beanName对应的Bean的类型,例如:com.joonwhee.open.demo.service.impl.UserServiceImpl
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
// 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
// 该拷贝副本取代mdb用于后续的操作
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
if (bean != null) {
return bean;
}
}
// 5.创建Bean实例(真正创建Bean的方法)
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
doCreateBean方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 1.新建Bean包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 2.如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
// *********重点*********
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 3.根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 4.拿到创建好的Bean实例
final Object bean = instanceWrapper.getWrappedInstance();
// 5.拿到Bean实例的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
// Autowired注解正是通过此方法实现注入类型的预解析
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;
}
}
// 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 8.提前曝光beanName的ObjectFactory,放入到Sprign的三级缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.初始化bean实例。
Object exposedObject = bean;
try {
// 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//......
return exposedObject;
}
createBeanInstance创建Bean实例方法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
// 解析bean的类型信息,
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// beanClass != null && 当前类不是public && 不允许访问非公共构造函数和方法。抛出异常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 1. 是否有bean的 Supplier 接口,如果有,通过回调来创建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 2. 如果工厂方法不为空,则使用工厂方法初始化策略
// 通过 @Bean 注解方法注入的bean或者xml 配置factory-method属性注入的
// BeanDefinition 会存在这个值。而注入这个bean的方法就是工厂方法。后面会详细解读
if (mbd.getFactoryMethodName() != null) {
// 执行工厂方法,创建bean
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
/* 3. 尝试使用构造函数构建bean,后面详解
* 经过上面两步,Spring确定没有其他方式来创建bean,所以打算使用构造函数来进行创建bean。
* 但是 bean 的构造函数可能有多个,需要确定使用哪一个。
*/
// resolved 表示构造函数是否已经解析完成
boolean resolved = false;
// autowireNecessary: 是否需要自动注入(即是否需要解析构造函数参数)
boolean autowireNecessary = false;
if (args == null) {
// 2.加锁
synchronized (mbd.constructorArgumentLock) {
// 一个类可能有多个不同的构造函数,每个构造函数参数列表不同,所以调用前需要根据参数锁定对应的构造函数或工程方法
// 如果这个bean的构造函数或者工厂方法已经解析过了,会保存到 mbd.resolvedConstructorOrFactoryMethod 中。这里来判断是否已经解析过了。
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 2.1 则将resolved标记为已解析
resolved = true;
// 2.2 根据constructorArgumentsResolved判断是否需要自动注入
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析过则使用功能解析好的构造函数方法,不需要再次解析。
// 这里的是通过 mbd.resolvedConstructorOrFactoryMethod 属性来缓存解析过的构造函数。
if (resolved) {
if (autowireNecessary) {
// 3.1 需要自动注入,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 3.2 否则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
}
// Spring通过调用后置处理器的determineCandidateConstructors方法将所有被@Autowired标注的构造方法给查找了出来,
// 如果不存在缓存则需要进行解析,这里通过 determineConstructorsFromBeanPostProcessors 方法调用了
// SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors 的后处理器方法来进行解析,
// Spring 默认的实现在AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors 方法中。
// 通过determineCandidateConstructors 方法获取到了候选的构造函数(因为满足条件的构造函数可能不止一个,需要进行进一步的选择)。
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 5.如果ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
// 6.没有特殊处理,则使用默认的构造函数进行bean的实例化
return instantiateBean(beanName, mbd);
}
创建实例的方法通常有以下几种:
Supplier方法 : 留给用户可以进行扩展的方法
public class CustomSupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
//自己定义了 supplier
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
beanDefinition.setInstanceSupplier(SupplierObject::create);
System.out.println("do Custom Supplier BeanFactoryPostProcessor");
}
// 没有定义 supplier,这样也可以。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("student");
beanDefinition.setInstanceSupplier(()->{
Student custom = new Student();
custom.setStudentName("zhao");
return custom;
});
System.out.println("do Custom Supplier BeanFactoryPostProcessor");
}
}
工厂方法:https://www.cnblogs.com/javastack/p/13431216.html
构造函数自动装配(通常指带有参数的构造函数)
简单实例化
1、通过BeanUtils,它使用了JVM的反射功能来生成Java对象实例
2、用CGLIB来生成,CGLIB是一种常用的字节码生成器的类库
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// 如果MethOverrides为空.
// spring有两个标签参数会产生MethodOverrides ,分别是 lookup-method,replaced-method
// 其中replaced-method使用方法 https://blog.csdn.net/wang0907/article/details/114325252
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获取bd.resolvedConstructorOrFactoryMethod已解析的构造器或工厂方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// 如果为空
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
// 如果是接口,抛出异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
else {
//通过bean的类clazz来得到声明的构造函数
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
// 并赋值回给bd.resolvedConstructorOrFactoryMethod
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过BeanUtils方法实例化bean
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 如果MethodOverrides不为空,生成cglib的子类
return instantiateWithMethodInjection(bd, beanName, owner);
}
}