HuiFer 带你读懂 BeanFactory getBean 方法

2024-01-31 15:32

本文主要是介绍HuiFer 带你读懂 BeanFactory getBean 方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring BeanFactory

  • Author: HuiFer
  • 源码阅读仓库: SourceHot-spring

BeanFactory 概述

  • org.springframework.beans.factory.BeanFactory

类图

在这里插入图片描述

方法列表

  • 贴出部分代码. 仅表示方法作用
public interface BeanFactory {// 从容器中根据beanname获取Object getBean(String name) throws BeansException;// 延迟加载对象<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);// 是否存在beanNameboolean containsBean(String name);// 这个 beanName 是否是单例的. 映射成 beanboolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 是否多例.boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 类型是否匹配boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;// 获取bean的类型Class<?> getType(String name) throws NoSuchBeanDefinitionException;// 获取别名String[] getAliases(String name);
}

解析

用例

bean 的实例化有如下几种方法

  1. 静态方法
  2. 工厂方法创建
  3. FactoryBean 接口创建

代码部分

public class UserBean {private String name;private Integer age;public static UserBean createInstance() {UserBean userBean = new UserBean();userBean.setAge(18);userBean.setName("zhangsan");return userBean;}// get set 忽略
}
public interface UserBeanFactory {UserBean factory();
}public class UserBeanFactoryImpl implementsUserBeanFactory {@Overridepublic UserBean factory() {return UserBean.createInstance();}
}
public class UserFactoryBean implements FactoryBean<UserBean> {@Overridepublic boolean isSingleton() {return true;}@Overridepublic UserBean getObject() throws Exception {return UserBean.createInstance();}@Overridepublic Class<?> getObjectType() {return UserBean.class;}
}
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd"><!--  静态方法--><bean id="static-method-user"class="org.source.hot.spring.overview.ioc.bean.init.UserBean"factory-method="createInstance"/><!--  工厂方法创建--><bean id="factory-use" class="org.source.hot.spring.overview.ioc.bean.init.UserBean"factory-bean="userFactory" factory-method="factory"></bean><!--user 工厂bean--><bean id="userFactory"class="org.source.hot.spring.overview.ioc.bean.init.UserBeanFactoryImpl"/><!--factory bean--><bean id="factory-bean-user"class="org.source.hot.spring.overview.ioc.bean.init.UserFactoryBean"/></beans>
public class SpringBeanInstantiation {public static void main(String[] args) {BeanFactory context = new ClassPathXmlApplicationContext("META-INF/beans/spring-bean-instantiation.xml");UserBean staticMethodBean = context.getBean("static-method-user", UserBean.class);UserBean factoryUser = context.getBean("factory-use", UserBean.class);UserBean factoryBean = context.getBean("factory-bean-user", UserBean.class);System.out.println();}
}

分析

  • 对下面代码进行分析
 UserBean staticMethodBean = context.getBean("static-method-user", UserBean.class);
  • org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.String, java.lang.Class<T>)
@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {// 判断 beanFactory 是否存活assertBeanFactoryActive();// 1. 获取 beanFactory// 2. 根据 beanName + class 获取 Beanreturn getBeanFactory().getBean(name, requiredType);}
  • 从方法参数
    • name: beanName
    • requiredType: 唯一的类型. 对象类型

assertBeanFactoryActive

  • beanFactory 是否存活判断
protected void assertBeanFactoryActive() {// 是否存活if (!this.active.get()) {// 是否关闭if (this.closed.get()) {throw new IllegalStateException(getDisplayName() + " has been closed already");}else {throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");}}}

getBeanFactory

  • 获取beanFactory

    • 获取方法是一个抽象方法

      public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
      
      • 子类实现

        org.springframework.context.support.AbstractRefreshableApplicationContext#getBeanFactory

        @Override
        public final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {if (this.beanFactory == null) {throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}return this.beanFactory;}
        }
        
        • org.springframework.context.support.GenericApplicationContext#getBeanFactory
        @Override
        public final ConfigurableListableBeanFactory getBeanFactory() {return this.beanFactory;
        }
        
  • 获取到的对象是org.springframework.beans.factory.support.DefaultListableBeanFactory

在这里插入图片描述

  • 整体类图

在这里插入图片描述

doGetBean

  • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    获取 bean 的核心

transformedBeanName
protected String transformedBeanName(String name) {// 转换 beanName .// 1. 通过·BeanFactoryUtils.transformedBeanName· 求beanName// 2. 如果是有别名的(方法参数是别名) . 会从别名列表中获取对应的 beanNamereturn canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public static String transformedBeanName(String name) {Assert.notNull(name, "'name' must not be null");// 名字不是 & 开头直接返回if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {return name;}// 截取字符串 在返回return transformedBeanNameCache.computeIfAbsent(name, beanName -> {do {beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());}while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));return beanName;});
}
public String canonicalName(String name) {String canonicalName = name;// Handle aliasing...String resolvedName;do {// 别名的获取resolvedName = this.aliasMap.get(canonicalName);if (resolvedName != null) {canonicalName = resolvedName;}}while (resolvedName != null);return canonicalName;
}

别名对象

private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
<bean id="factory-bean-user"class="org.source.hot.spring.overview.ioc.bean.init.UserFactoryBean"/><alias name="factory-bean-user" alias="userFactoryBean"/>

aliasMap 和 别名标签的对应关系

在这里插入图片描述

alias标签的alias值作为别名的key , alias 标签的 name 值作为 value

getSingleton
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)
@Override
@Nullable
public Object getSingleton(String beanName) {return getSingleton(beanName, true);
}
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {// 尝试从单例缓存中获取Object singletonObject = this.singletonObjects.get(beanName);// 单例对象是否null// 这个 beanName 是否正在创建if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {// 锁synchronized (this.singletonObjects) {// 从延迟加载的map中获取singletonObject = this.earlySingletonObjects.get(beanName);// 对象是否空 , 是否允许提前应用if (singletonObject == null && allowEarlyReference) {// 从对象工厂map中获取对象工厂ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 对象获取后设置singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;
}
  • 相关属性值
/***  Cache of singleton objects: bean name to bean instance.** 单例对象容器, key: beanName , value: bean实例* */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/***  Cache of singleton factories: bean name to ObjectFactory.* key: beanName* value: 对象工厂* */private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/***  Names of beans that are currently in creation.** 当前正在实例化的beanName** */private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
getObjectForBeanInstance
  • org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
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.// 判断 beanName 是不是 bean 工厂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.// 判断是否是 factoryBeanif (!(beanInstance instanceof FactoryBean)) {return beanInstance;}Object object = null;if (mbd != null) {mbd.isFactoryBean = true;}else {// 缓存中获取object = getCachedObjectForFactoryBean(beanName);}if (object == null) {// Return bean instance from factory.// 如果还是 null 从 factory bean 中创建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());// 从 FactoryBean 中获取bean实例object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}
getObjectFromFactoryBean
  • org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean

  • 从 FactoryBean 中获取对象

	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {// 是否单例 是否已经包含if (factory.isSingleton() && containsSingleton(beanName)) {synchronized (getSingletonMutex()) {// 从工厂bean的缓存中获取Object object = this.factoryBeanObjectCache.get(beanName);if (object == null) {// 从 factoryBean 接口中获取object = doGetObjectFromFactoryBean(factory, beanName);// Only post-process and store if not put there already during getObject() call above// (e.g. because of circular reference processing triggered by custom getBean calls)// 从缓存map中获取Object alreadyThere = this.factoryBeanObjectCache.get(beanName);if (alreadyThere != null) {// 如果缓存中获取有值// object 覆盖object = alreadyThere;}else {if (shouldPostProcess) {if (isSingletonCurrentlyInCreation(beanName)) {// Temporarily return non-post-processed object, not storing it yet..return object;}// 单例创建前的验证beforeSingletonCreation(beanName);try {// 从 FactoryBean 接口创建的 后置处理object = postProcessObjectFromFactoryBean(object, beanName);}catch (Throwable ex) {throw new BeanCreationException(beanName,"Post-processing of FactoryBean's singleton object failed", ex);}finally {// 单例bean创建之后afterSingletonCreation(beanName);}}// 是否包含bean nameif (containsSingleton(beanName)) {// 插入缓存// 后续使用的时候可以直接获取this.factoryBeanObjectCache.put(beanName, object);}}}return object;}}else {Object object = doGetObjectFromFactoryBean(factory, beanName);if (shouldPostProcess) {try {object = postProcessObjectFromFactoryBean(object, beanName);}catch (Throwable ex) {throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);}}return object;}}
beforeSingletonCreation
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation

  • 单例创建前的验证

protected void beforeSingletonCreation(String beanName) {// 排除的单例beanName 是否包含当前beanName// 添加当前正在初始化的beanName 是否正确if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}
}
postProcessObjectFromFactoryBean
  • 两种实现

    • org.springframework.beans.factory.support.FactoryBeanRegistrySupport#postProcessObjectFromFactoryBean

      protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {return object;
      }
      

      直接返回 object

    • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean 调用 BeanPostProcessor

      	@Overrideprotected Object postProcessObjectFromFactoryBean(Object object, String beanName) {return applyBeanPostProcessorsAfterInitialization(object, beanName);}@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}
  • 两个方法军返回 Bean 对象 . 一种是直接返回 。 另一种是执行接口 BeanPostProcessor 接口返回

afterSingletonCreation
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#afterSingletonCreation
protected void afterSingletonCreation(String beanName) {// 排除的单例beanName 是否包含当前beanName// 移除当前正在初始化的beanName 是否正确if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");}
}
  • 代码现在进入的很深了,回到 doGetBean
  • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {// 转换beanNamefinal String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons.// 获取单例对象Object sharedInstance = getSingleton(beanName);// 单例对象是否存在 参数是否为空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 + "'");}}// 实例化beanbean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}// 省略后续内容}
  • 目前未知doGetBean的第一个if分支已经分析完毕. 接下来看下面的代码

  • 下面这段代码就简单说一下就跳过了。

    • 从 容器中获取,最后还是回到doGetBean方法中. 来进行bean创建 这里不进行展开。
else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.// 循环依赖的问题if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}
markBeanAsCreated
  • org.springframework.beans.factory.support.AbstractBeanFactory#markBeanAsCreated

  • 方法作用将bean标记为已创建

protected void markBeanAsCreated(String beanName) {// 已创建的beanName 是否包含当前beanNameif (!this.alreadyCreated.contains(beanName)) {synchronized (this.mergedBeanDefinitions) {if (!this.alreadyCreated.contains(beanName)) {// Let the bean definition get re-merged now that we're actually creating// the bean... just in case some of its metadata changed in the meantime.// 将属性stale设置trueclearMergedBeanDefinition(beanName);// 放入已创建集合中this.alreadyCreated.add(beanName);}}}
}
protected void clearMergedBeanDefinition(String beanName) {RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName);if (bd != null) {bd.stale = true;}
}
  • stale 的解释

    /***  Determines if the definition needs to be re-merged.* 是否需要重新合并定义* */
    volatile boolean stale;
    
  • 属性值 已创建的beanName

    private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
    
getMergedLocalBeanDefinition
  • org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition

  • 这个方法获取一个RootBeanDefinition对象 , 这个对象也是bean的一种定义。

  • 从目前的几个方法名称来看,暂且认为这是一个合并了多个 BeanDefinition的对象吧

在这里插入图片描述

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {// Quick check on the concurrent map first, with minimal locking.// 缓存中获取RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);if (mbd != null && !mbd.stale) {return mbd;}// 合并的 bean 定义return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)throws BeanDefinitionStoreException {return getMergedBeanDefinition(beanName, bd, null);}
getBeanDefinition
  • 获取 beanDefinition
  • org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanDefinition
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {BeanDefinition bd = this.beanDefinitionMap.get(beanName);if (bd == null) {if (logger.isTraceEnabled()) {logger.trace("No bean named '" + beanName + "' found in " + this);}throw new NoSuchBeanDefinitionException(beanName);}return bd;
}
  • 从 beanDefinition map 中获取

  • 相关属性

    	/*** Map of bean definition objects, keyed by bean name.** key: beanName* value: BeanDefinition**  */private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    
getMergedBeanDefinition
  • 获取RootBeanDefinition

  • org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.config.BeanDefinition)

  • 第一部分代码

    • map 中获取 RootBeanDefinition
    • 是否存在父名称
    • 类型是否是 RootBeanDefinition
      • 是: 拷贝
      • 否: 将 BeanDefinition 转换成 RootBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;RootBeanDefinition previous = null;// Check with full lock now in order to enforce the same merged instance.if (containingBd == null) {// 从缓存中获取mbd = this.mergedBeanDefinitions.get(beanName);}if (mbd == null || mbd.stale) {previous = mbd;// 是否存在父名称if (bd.getParentName() == null) {// Use copy of given root bean definition.// 类型是否等于RootBeanDefinitionif (bd instanceof RootBeanDefinition) {// 做一次对象拷贝mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {// 将 beanDefinition 创建成 RootBeanDefinitionmbd = new RootBeanDefinition(bd);}}// 省略其他}
  • 相关属性

    /*** Map from bean name to merged RootBeanDefinition.* key: beanName* value: RootBeanDefinition*  */
    private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
    
  • 克隆 方法

    /*** 克隆 BeanDefinition* @return*/
    @Override
    public RootBeanDefinition cloneBeanDefinition() {return new RootBeanDefinition(this);
    }
    
  • 第二部分代码

{// Child bean definition: needs to be merged with parent.// 父BeanDefinitionBeanDefinition pbd;try {// 父类beanNameString parentBeanName = transformedBeanName(bd.getParentName());// 当前beanName是否等于父的beanNameif (!beanName.equals(parentBeanName)) {// 存在父 beanName// 父 beanDefinition// 递归调用pbd = getMergedBeanDefinition(parentBeanName);}else {// 获取父 beanFactoryBeanFactory parent = getParentBeanFactory();// beanFactory 类型判断if (parent instanceof ConfigurableBeanFactory) {// ConfigurableBeanFactory 的获取方式pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);}else {throw new NoSuchBeanDefinitionException(parentBeanName,"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +"': cannot be resolved without an AbstractBeanFactory parent");}}}catch (NoSuchBeanDefinitionException ex) {throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);}// Deep copy with overridden values.// 将 父 BeanDefinition 对象拷贝mbd = new RootBeanDefinition(pbd);// 覆盖 beanDefinitionmbd.overrideFrom(bd);}
overrideFrom
  • 覆盖方法

  • org.springframework.beans.factory.support.AbstractBeanDefinition#overrideFrom

  • 最后一段

   // Set default singleton scope, if not configured before.// 作用域设置if (!StringUtils.hasLength(mbd.getScope())) {// 没有设置作用域直接给单例类型mbd.setScope(SCOPE_SINGLETON);}// A bean contained in a non-singleton bean cannot be a singleton itself.// Let's correct this on the fly here, since this might be the result of// parent-child merging for the outer bean, in which case the original inner bean// definition will not have inherited the merged outer bean's singleton status.// 修正 作用域if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {mbd.setScope(containingBd.getScope());}// Cache the merged bean definition for the time being// (it might still get re-merged later on in order to pick up metadata changes)if (containingBd == null && isCacheBeanMetadata()) {// 放入缓存this.mergedBeanDefinitions.put(beanName, mbd);}
}
if (previous != null) {copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
checkMergedBeanDefinition
  • org.springframework.beans.factory.support.AbstractBeanFactory#checkMergedBeanDefinition

    protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)throws BeanDefinitionStoreException {if (mbd.isAbstract()) {throw new BeanIsAbstractException(beanName);}
    }
    
    • 判断是否 abstract 标记的情况
  • 继续回到 doGetBean 方法

// 需要依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// 注册依赖beanregisterDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}
}
isDependent
  • 是否存在依赖关系

  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#isDependent(java.lang.String, java.lang.String, java.util.Set<java.lang.String>)

private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {if (alreadySeen != null && alreadySeen.contains(beanName)) {return false;}// 别名String canonicalName = canonicalName(beanName);// 依赖列表中获取Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);if (dependentBeans == null) {return false;}if (dependentBeans.contains(dependentBeanName)) {return true;}for (String transitiveDependency : dependentBeans) {if (alreadySeen == null) {alreadySeen = new HashSet<>();}alreadySeen.add(beanName);if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {return true;}}return false;
}
  • 相关属性

    /*** Map between dependent bean names: bean name to Set of dependent bean names.** key: bean* value: 依赖列表* */
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
    
  • 一个用例

<bean class="org.source.hot.spring.overview.ioc.bean.init.SystemUserBean" ><property name="userBean" ref="factory-use"/>
</bean>

在这里插入图片描述

registerDependentBean
  • 注册依赖关系
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerDependentBean
    • 在前文调用 isDependent 方法的的时候我们找到了一个依赖映射dependentBeanMap ,在这个方法中会将依赖关系放入dependentBeanMap
public void registerDependentBean(String beanName, String dependentBeanName) {// 别名String canonicalName = canonicalName(beanName);synchronized (this.dependentBeanMap) {// 向依赖关系中放入数据Set<String> dependentBeans =this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));if (!dependentBeans.add(dependentBeanName)) {return;}}synchronized (this.dependenciesForBeanMap) {Set<String> dependenciesForBean =this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));dependenciesForBean.add(canonicalName);}
}
  • 再回到 doGetBean

  • 接下来就是实例化的过程了.

if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
getSingleton
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

  • 获取单例对象

    1. 从单例对象的map缓存中获取
    2. 从 ObjectFactory 中获取
  • 周边方法

    • beforeSingletonCreation

    • afterSingletonCreation

    • addSingleton

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {// 从单例对象缓存中获取Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {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 + "'");}// 单例创建前的验证beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {// 从 ObjectFactory 中获取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;}// 创建单例对象后的验证afterSingletonCreation(beanName);}if (newSingleton) {// 添加到 单例容器中addSingleton(beanName, singletonObject);}}return singletonObject;}
}
  • 回到 doGetBean 方法中

    if (mbd.isSingleton()) {// 判断是否是单例sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    

    这里又要给 createBean方法, 从 getSingleton 的参数看可以知道 ,第二个匿名函数是ObjectFactory接口实现.

    @FunctionalInterface
    public interface ObjectFactory<T> {/*** Return an instance (possibly shared or independent)* of the object managed by this factory.* 获取对象* @return the resulting instance* @throws BeansException in case of creation errors*/T getObject() throws BeansException;}
    
    • createBean 返回的就是单例bean对象的实例
createBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

  • 两个核心方法

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
resolveBeforeInstantiation
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

  • 方法概述:

    获取BeanPostProcessor接口的实现列表

    • applyBeanPostProcessorsBeforeInstantiation 前置方法执行
    • applyBeanPostProcessorsAfterInitialization后置方法执行
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {/*** 主要实现{@link org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(java.lang.Class, java.lang.String)}*/bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;
}
doCreateBean
  • 创建 bean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
		// Instantiate the bean.BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {// beanFactory 移除当前创建的beanNameinstanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}// beanWrapper 是否存在if (instanceWrapper == null) {// 创建 bean 实例instanceWrapper = createBeanInstance(beanName, mbd, args);}
createBeanInstance
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
  • 创建 bean 实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {// Make sure bean class is actually resolved at this point.// 获取 bean classClass<?> beanClass = resolveBeanClass(mbd, beanName);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());}// 返回一个用来创建bean实例的回调接口// Supplier get 直接获取bean对象Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}if (mbd.getFactoryMethodName() != null) {// 通过工厂方法创建return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {if (autowireNecessary) {// 自动构造 beanreturn autowireConstructor(beanName, mbd, null, null);}else {// 实例化beanreturn instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);
}
resolveBeanClass
  • org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
  • 获取bean 的class
@Nullable
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)throws CannotLoadBeanClassException {try {// 是否包含 bean 类型if (mbd.hasBeanClass()) {// 直接返回return mbd.getBeanClass();}if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());}else {// 从 bean definition 中获取return doResolveBeanClass(mbd, typesToMatch);}}catch (PrivilegedActionException pae) {ClassNotFoundException ex = (ClassNotFoundException) pae.getException();throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (ClassNotFoundException ex) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (LinkageError err) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);}
}
doResolveBeanClass
  • org.springframework.beans.factory.support.AbstractBeanFactory#doResolveBeanClass

  • 第一段

    ClassLoader beanClassLoader = getBeanClassLoader();
    ClassLoader dynamicLoader = beanClassLoader;
    boolean freshResolve = false;// 判断 typesToMatch 是否为空
    if (!ObjectUtils.isEmpty(typesToMatch)) {// When just doing type checks (i.e. not creating an actual instance yet),// use the specified temporary class loader (e.g. in a weaving scenario).// 获取临时类加载器ClassLoader tempClassLoader = getTempClassLoader();if (tempClassLoader != null) {dynamicLoader = tempClassLoader;freshResolve = true;// 类型比较if (tempClassLoader instanceof DecoratingClassLoader) {DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;for (Class<?> typeToMatch : typesToMatch) {// 添加排除的类dcl.excludeClass(typeToMatch.getName());}}}
    }
    
  • 第二段

    if (className != null) {// bean 属性值Object evaluated = evaluateBeanDefinitionString(className, mbd);if (!className.equals(evaluated)) {// A dynamically resolved expression, supported as of 4.2...if (evaluated instanceof Class) {return (Class<?>) evaluated;}else if (evaluated instanceof String) {className = (String) evaluated;freshResolve = true;}else {throw new IllegalStateException("Invalid class name expression result: " + evaluated);}}
    
evaluateBeanDefinitionString
@Nullable
protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) {// 占位符解析if (this.beanExpressionResolver == null) {return value;}Scope scope = null;if (beanDefinition != null) {// 获取 scopeString scopeName = beanDefinition.getScope();if (scopeName != null) {// scope 转换成 接口值scope = getRegisteredScope(scopeName);}}// 返回对象return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
}
evaluate
  • org.springframework.context.expression.StandardBeanExpressionResolver#evaluate
	@Override@Nullablepublic Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException {if (!StringUtils.hasLength(value)) {return value;}try {Expression expr = this.expressionCache.get(value);if (expr == null) {// el表达式解析expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);// 解析结果放入缓存this.expressionCache.put(value, expr);}// spring 中默认的表达式上下文StandardEvaluationContext sec = this.evaluationCache.get(evalContext);if (sec == null) {// 设置属性sec = new StandardEvaluationContext(evalContext);sec.addPropertyAccessor(new BeanExpressionContextAccessor());sec.addPropertyAccessor(new BeanFactoryAccessor());sec.addPropertyAccessor(new MapAccessor());sec.addPropertyAccessor(new EnvironmentAccessor());sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));ConversionService conversionService = evalContext.getBeanFactory().getConversionService();if (conversionService != null) {sec.setTypeConverter(new StandardTypeConverter(conversionService));}customizeEvaluationContext(sec);this.evaluationCache.put(evalContext, sec);}// 把值获取return expr.getValue(sec);}catch (Throwable ex) {throw new BeanExpressionException("Expression parsing failed", ex);}}
  • 类图

在这里插入图片描述

BeanExpressionContext
  • 两个属性
private final ConfigurableBeanFactory beanFactory;@Nullable
private final Scope scope;
  • 几个方法
public boolean containsObject(String key) {return (this.beanFactory.containsBean(key) ||(this.scope != null && this.scope.resolveContextualObject(key) != null));
}@Nullable
public Object getObject(String key) {if (this.beanFactory.containsBean(key)) {return this.beanFactory.getBean(key);}else if (this.scope != null) {return this.scope.resolveContextualObject(key);}else {return null;}
}

beanName 是否存在

根据 beanName 获取 bean 实例

  • 回到解析方法
parseExpression
@Override
public Expression parseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {if (context != null && context.isTemplate()) {// 是否使用 template 解析return parseTemplate(expressionString, context);}else {// 自定义的解析规则return doParseExpression(expressionString, context);}
}
  • doParseExpression

    • spring 中的两种解析方式
      • org.springframework.expression.spel.standard.InternalSpelExpressionParser#doParseExpression
      • org.springframework.expression.spel.standard.SpelExpressionParser#doParseExpression
  • parseTemplate 方法

    • org.springframework.expression.common.TemplateAwareExpressionParser#parseTemplate
private Expression parseTemplate(String expressionString, ParserContext context) throws ParseException {// 表达式为空if (expressionString.isEmpty()) {// 创建空的 LiteralExpressionreturn new LiteralExpression("");}// 表达式解析成接口Expression[] expressions = parseExpressions(expressionString, context);if (expressions.length == 1) {return expressions[0];}else {// 返回字符串的表达式return new CompositeStringExpression(expressionString, expressions);}
}

在这里插入图片描述

  • parseExpressions

    • org.springframework.expression.common.TemplateAwareExpressionParser#parseExpressions
    • 说简单一些这个地方就是拿出表达式的值
  • 回到 evaluate 方法

StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
if (sec == null) {// 设置属性sec = new StandardEvaluationContext(evalContext);sec.addPropertyAccessor(new BeanExpressionContextAccessor());sec.addPropertyAccessor(new BeanFactoryAccessor());sec.addPropertyAccessor(new MapAccessor());sec.addPropertyAccessor(new EnvironmentAccessor());sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));ConversionService conversionService = evalContext.getBeanFactory().getConversionService();if (conversionService != null) {sec.setTypeConverter(new StandardTypeConverter(conversionService));}customizeEvaluationContext(sec);this.evaluationCache.put(evalContext, sec);
}
// 把值获取
return expr.getValue(sec);
  • 最后一句 getValue

    • org.springframework.expression.common.LiteralExpression#getValue(org.springframework.expression.EvaluationContext)

      刚才流程中我们可以看到 exprLiteralExpression

      @Override
      public String getValue(EvaluationContext context) {return this.literalValue;
      }
      

      直接返回字符串. 这个字符串就是刚才放进去的 el表达式

往外跳 找到方法 doResolveBeanClass

if (className != null) {// bean 属性值Object evaluated = evaluateBeanDefinitionString(className, mbd);if (!className.equals(evaluated)) {// A dynamically resolved expression, supported as of 4.2...if (evaluated instanceof Class) {return (Class<?>) evaluated;}else if (evaluated instanceof String) {className = (String) evaluated;freshResolve = true;}else {throw new IllegalStateException("Invalid class name expression result: " + evaluated);}}if (freshResolve) {// When resolving against a temporary class loader, exit early in order// to avoid storing the resolved Class in the bean definition.if (dynamicLoader != null) {try {return dynamicLoader.loadClass(className);}catch (ClassNotFoundException ex) {if (logger.isTraceEnabled()) {logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);}}}return ClassUtils.forName(className, dynamicLoader);}
}
  • 目前为止我们解析了 第一句话 Object evaluated = evaluateBeanDefinitionString(className, mbd); 接下来往下走看一下具体的 class 返回对象
  1. 类型等于 class 直接返回
  2. 类型等于 String 的两种返回方式
    1. ClassLoader.loadClass 返回
    2. ClassUtils.forName 返回
      1. 底层方法为 java.lang.Class#forName(java.lang.String, boolean, java.lang.ClassLoader)
resolveBeanClass
  • 回到doResolveBeanClass方法中.最后一行

    // Resolve regularly, caching the result in the BeanDefinition...
    return mbd.resolveBeanClass(beanClassLoader);
    
@Nullable
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {// 获取beanClassNameString className = getBeanClassName();if (className == null) {return null;}// 加载类Class<?> resolvedClass = ClassUtils.forName(className, classLoader);this.beanClass = resolvedClass;// 返回return resolvedClass;
}
  • 获取 beanClassName
@Override
@Nullable
public String getBeanClassName() {Object beanClassObject = this.beanClass;if (beanClassObject instanceof Class) {return ((Class<?>) beanClassObject).getName();}else {return (String) beanClassObject;}
}
  • 回到createBeanInstance
    • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
// 返回一个用来创建bean实例的回调接口
// Supplier get 直接获取bean对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);
}
obtainFromSupplier
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {Object instance;// 获取当前的bean实例String outerBean = this.currentlyCreatedBean.get();// 设置当前处理的beanNamethis.currentlyCreatedBean.set(beanName);try {// 从 Supplier 中获取instance = instanceSupplier.get();}finally {if (outerBean != null) {// 如果 currentlyCreatedBean 取不到设置 this.currentlyCreatedBean.set(outerBean);}else {// 移除this.currentlyCreatedBean.remove();}}if (instance == null) {// supplier 中获取不到, 将实例设置为 NullBeaninstance = new NullBean();}// beanWrapper 包装BeanWrapper bw = new BeanWrapperImpl(instance);// beanWrapper 实例化后的操作initBeanWrapper(bw);return bw;
}
  • Supplier 代码如下
@FunctionalInterface
public interface Supplier<T> {/*** Gets a result.** @return a result*/T get();
}
initBeanWrapper
protected void initBeanWrapper(BeanWrapper bw) {// 设置转换服务bw.setConversionService(getConversionService());// 注册自定义属性编辑器registerCustomEditors(bw);
}
registerCustomEditors
protected void registerCustomEditors(PropertyEditorRegistry registry) {PropertyEditorRegistrySupport registrySupport =(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);if (registrySupport != null) {registrySupport.useConfigValueEditors();}if (!this.propertyEditorRegistrars.isEmpty()) {for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {try {// 属性编辑器,注册自定义属性编辑器registrar.registerCustomEditors(registry);}catch (BeanCreationException ex) {Throwable rootCause = ex.getMostSpecificCause();if (rootCause instanceof BeanCurrentlyInCreationException) {BeanCreationException bce = (BeanCreationException) rootCause;String bceBeanName = bce.getBeanName();if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {if (logger.isDebugEnabled()) {logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +"] failed because it tried to obtain currently created bean '" +ex.getBeanName() + "': " + ex.getMessage());}onSuppressedException(ex);continue;}}throw ex;}}}if (!this.customEditors.isEmpty()) {this.customEditors.forEach((requiredType, editorClass) ->registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));}
}
  • 最后调用

    org.springframework.beans.support.ResourceEditorRegistrar#registerCustomEditors

registerCustomEditors
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);doRegisterEditor(registry, Resource.class, baseEditor);doRegisterEditor(registry, ContextResource.class, baseEditor);doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));doRegisterEditor(registry, File.class, new FileEditor(baseEditor));doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));ClassLoader classLoader = this.resourceLoader.getClassLoader();doRegisterEditor(registry, URI.class, new URIEditor(classLoader));doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));if (this.resourceLoader instanceof ResourcePatternResolver) {doRegisterEditor(registry, Resource[].class,new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));}
}
doRegisterEditor
private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {if (registry instanceof PropertyEditorRegistrySupport) {// 属性编辑器覆盖默认的编辑器((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);}else {// 注册自定义的属性编辑器registry.registerCustomEditor(requiredType, editor);}
}

覆盖默认编辑器

public void overrideDefaultEditor(Class<?> requiredType, PropertyEditor propertyEditor) {if (this.overriddenDefaultEditors == null) {this.overriddenDefaultEditors = new HashMap<>();}this.overriddenDefaultEditors.put(requiredType, propertyEditor);
}
  • registerCustomEditor
@Override
public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) {if (requiredType == null && propertyPath == null) {throw new IllegalArgumentException("Either requiredType or propertyPath is required");}if (propertyPath != null) {if (this.customEditorsForPath == null) {this.customEditorsForPath = new LinkedHashMap<>(16);}this.customEditorsForPath.put(propertyPath, new CustomEditorHolder(propertyEditor, requiredType));}else {if (this.customEditors == null) {this.customEditors = new LinkedHashMap<>(16);}// 放入 customEditors map对象中this.customEditors.put(requiredType, propertyEditor);this.customEditorCache = null;}
}

到这里 createBeanInstance 流程已经完毕

回到doCreateBean 方法

// beanWrapper 是否存在
if (instanceWrapper == null) {// 创建 bean 实例instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获取 实例
final Object bean = instanceWrapper.getWrappedInstance();
// beanWrapper中存储的实例.class
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;
}

紧接着两行代码 获取 bean 实例 和beanType

applyMergedBeanDefinitionPostProcessors
synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// 后置方法执行 BeanPostProcessor applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}
}
  • applyMergedBeanDefinitionPostProcessors 方法会执行所有的后置方法.
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof MergedBeanDefinitionPostProcessor) {MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);}}
}
addSingletonFactory
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory

  • 继续回到 doCreateBean

// 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));
}
  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory

    添加单例工厂

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {// 添加单例对象工厂this.singletonFactories.put(beanName, singletonFactory);// 删除单例BeanNamethis.earlySingletonObjects.remove(beanName);// 注册单例beanNamethis.registeredSingletons.add(beanName);}}
}
getEarlyBeanReference
  • org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {// 尝试获取缓存Object cacheKey = getCacheKey(bean.getClass(), beanName);// 加入缓存this.earlyProxyReferences.put(cacheKey, bean);// 代理对象return wrapIfNecessary(bean, beanName, cacheKey);
}
  • wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {// 这个bean是否处理过if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}// 这个bean是否需要代理if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}// 1.bean.class是否是Spring接口类型 2. 是否为 AutowireCapableBeanFactory 接口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;
}
  • 回到下面代码中

    if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// 添加单例工厂addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    
    • 上述方法就是将结果bean放入
populateBean
// Initialize the bean instance.
Object exposedObject = bean;
try {populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);
}
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

  • 设置属性值

  • 概述一下方法

    • 自动注入的两种实现

      1. 根据类型
      2. 根据名称
    • xml 中的属性标签设置

      <bean class="org.source.hot.spring.overview.ioc.bean.init.UserBean"><property name="age" value="30"/>
      </bean>
      
    {if (bw == null) {if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");}else {// Skip property population phase for null instance.return;}}// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the// state of the bean before properties are set. This can be used, for example,// to support styles of field injection.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}}PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 获取自动注入的值int resolvedAutowireMode = mbd.getResolvedAutowireMode();// 自动注入if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {// 按照名称注入autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {// 按照类型注入autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}}if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}// 以来检查checkDependencies(beanName, mbd, filteredPds, pvs);}if (pvs != null) {// 应用属性applyPropertyValues(beanName, mbd, bw, pvs);}
    }
    

pvs 属性如下

在这里插入图片描述

applyPropertyValues
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
  • 属性设置
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {if (pvs.isEmpty()) {return;}if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());}MutablePropertyValues mpvs = null;// 没有解析的属性List<PropertyValue> original;if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;if (mpvs.isConverted()) {// Shortcut: use the pre-converted values as-is.try {bw.setPropertyValues(mpvs);return;}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);}}original = mpvs.getPropertyValueList();}else {original = Arrays.asList(pvs.getPropertyValues());}// 自定义转换器TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}//  创建BeanDefinitionValueResolverBeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);// Create a deep copy, resolving any references for values.// 解析后的对象集合List<PropertyValue> deepCopy = new ArrayList<>(original.size());boolean resolveNecessary = false;for (PropertyValue pv : original) {// 解析过的属性if (pv.isConverted()) {deepCopy.add(pv);}// 没有解析过的属性else {// 属性名称String propertyName = pv.getName();// 属性值,直接读取到的Object originalValue = pv.getValue();if (originalValue == AutowiredPropertyMarker.INSTANCE) {Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();if (writeMethod == null) {throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);}originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);}// 解析值Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);Object convertedValue = resolvedValue;/*** 1. isWritableProperty: 属性可写* 2. isNestedOrIndexedProperty: 是否循环嵌套*/boolean convertible = bw.isWritableProperty(propertyName) &&!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);if (convertible) {// 转换器解析convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);}// Possibly store converted value in merged bean definition,// in order to avoid re-conversion for every created bean instance.if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);}deepCopy.add(pv);}// 类型解析else if (convertible && originalValue instanceof TypedStringValue &&!((TypedStringValue) originalValue).isDynamic() &&!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);deepCopy.add(pv);}else {resolveNecessary = true;deepCopy.add(new PropertyValue(pv, convertedValue));}}}if (mpvs != null && !resolveNecessary) {mpvs.setConverted();}// Set our (possibly massaged) deep copy.try {bw.setPropertyValues(new MutablePropertyValues(deepCopy));}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);}
}

属性设置后跳出方法回到 doCreateBean

try {populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);
}

在这里插入图片描述

initializeBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

  • 我们可以看一下整个代码的流程

    1. aware 接口的执行
    2. BeanPostProcessor 前置方法执行
    3. bean实例化
    4. BeanPostProcessor 后置方法执行
    5. 返回bean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// aware 接口执行invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// BeanPostProcessor 前置方法执行wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 执行实例化函数invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {// BeanPostProcessor 后置方法执行wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
  • Aware 接口的执行
private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}j
  • 前置方法执行

    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;
    }
    
  • 后置方法执行

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {// 执行 spring 容器中 BeanPostProcessorObject current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;
    }
    
invokeInitMethods
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
  • 初始化方法重点看一下
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {// 是否是 InitializingBeanboolean isInitializingBean = (bean instanceof InitializingBean);// 是否存在方法 "afterPropertiesSet"if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {// 执行 afterPropertiesSetAccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {// 自定义的 init method invokeCustomInitMethod(beanName, bean, mbd);}}
}

在这里插入图片描述

我们现在的bean不是InitializingBean 会走自定义的init-mthod方法

  • 做一下改造实体对象

    public void initMethod() {this.name = "abc";this.age = 10;
    }
    
<bean class="org.source.hot.spring.overview.ioc.bean.init.UserBean"init-method="initMethod"><property name="age" value="30"/>
</bean>
  • 观察 initMethodName 会变成 标签属性init-method 的内容. 接下来就是通过反射执行方法

在这里插入图片描述

  • 在执行方法前将 bean 的信息先做一次截图

    在这里插入图片描述

  • 如果按照我们代码中的编写方式 bean 的属性会被覆盖

    在这里插入图片描述

invokeCustomInitMethod
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeCustomInitMethod
  • 执行 自定义的init-method 方法
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {// 获取 initMethod 名称String initMethodName = mbd.getInitMethodName();Assert.state(initMethodName != null, "No init method set");// 反射获取方法Method initMethod = (mbd.isNonPublicAccessAllowed() ?BeanUtils.findMethod(bean.getClass(), initMethodName) :ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));// 方法是否存在判断if (initMethod == null) {if (mbd.isEnforceInitMethod()) {throw new BeanDefinitionValidationException("Could not find an init method named '" +initMethodName + "' on bean with name '" + beanName + "'");}else {if (logger.isTraceEnabled()) {logger.trace("No default init method named '" + initMethodName +"' found on bean with name '" + beanName + "'");}// Ignore non-existent default lifecycle methods.return;}}if (logger.isTraceEnabled()) {logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");}// 尝试获取接口方法Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(methodToInvoke);return null;});try {// 反射调用AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->methodToInvoke.invoke(bean), getAccessControlContext());}catch (PrivilegedActionException pae) {InvocationTargetException ex = (InvocationTargetException) pae.getException();throw ex.getTargetException();}}else {try {// 反射调用ReflectionUtils.makeAccessible(methodToInvoke);methodToInvoke.invoke(bean);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}
}
getInterfaceMethodIfPossible
  • org.springframework.util.ClassUtils#getInterfaceMethodIfPossible
public static Method getInterfaceMethodIfPossible(Method method) {// 是不是 public// 是不是 接口if (!Modifier.isPublic(method.getModifiers()) || method.getDeclaringClass().isInterface()) {return method;}// 放入init-method 缓存return interfaceMethodCache.computeIfAbsent(method, key -> {Class<?> current = key.getDeclaringClass();while (current != null && current != Object.class) {// 当前类的 接口列表Class<?>[] ifcs = current.getInterfaces();for (Class<?> ifc : ifcs) {try {// 从接口中获取方法return ifc.getMethod(key.getName(), key.getParameterTypes());}catch (NoSuchMethodException ex) {// ignore}}current = current.getSuperclass();}return key;});
}
  • 跳出这个方法initializeBean 回到下面代码

    try {populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    
    • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

      其实到此bean已经创建完成可以直接返回了.

  • 再往外层跳

    org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    if (mbd.isSingleton()) {// 判断是否是单例sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    
    • 单例对象的创建bean已经完成啦…
  • 其他的两种创建,其本质还是 createBean 方法的调用.

// 原型模式创建
else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}else {String scopeName = mbd.getScope();final 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);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}
}
  • 再往外面跳一层 回到 getBean 方法.

  • 终于 getBean 方法底层调用分析结束.

这篇关于HuiFer 带你读懂 BeanFactory getBean 方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/664248

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“