java-spring 06 图灵 getBean方法和 doGetBean方法

01.一般的流程是,这里是从上一章的preInstantiateSingleton方法顺序过来的。

getBean() -> doGetBean() -> createBean() -> doCreateBean() -> createBeanInstance() -> populateBean() -> initializeBean()

02.getBean方法,一般就是调用doGetBean方法

	@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}

03.doGetBean方法

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {/*** 提取对应的beanName,有人可能会认为此处直接使用即可,为什么还要进行转换呢,原因在于当bean对象实现FactoryBean接口之后就会变成&beanName,同时如果存在别名,也需要把别名进行转换*/String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons./**提前检查单例缓存中是否有手动注册的单例对象,跟循环依赖有关联*/Object sharedInstance = getSingleton(beanName);// 如果bean的单例对象找到了,且没有创建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 + "'");}}// 返回对象的实例,这句话的重点在于当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}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.// 如果bean定义不存在,就检查父工厂是否有BeanFactory parentBeanFactory = getParentBeanFactory();// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】String nameToLookup = originalBeanName(name);// 如果父工厂是AbstractBeanFactory的实例if (parentBeanFactory instanceof AbstractBeanFactory) {// 调用父工厂的doGetBean方法,就是该方法。【递归】return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.// 如果有创建bean实例时要使用的参数// Delegation to parent with explicit args. 使用显示参数委派给父工厂// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型return parentBeanFactory.getBean(nameToLookup, requiredType);}else {// 使用父工厂获取bean,通过bean全类名return (T) parentBeanFactory.getBean(nameToLookup);}}// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录if (!typeCheckOnly) {// 为beanName标记为已经创建(或将要创建)markBeanAsCreated(beanName);}try {// 此处做了BeanDefinition对象的转换,当我们从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,// 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查mbd的合法性,不合格会引发验证异常checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.// 如果存在依赖的bean的话,那么则优先实例化依赖的beanString[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// 如果存在依赖,则需要递归实例化依赖的beanfor (String dep : dependsOn) {// 如果beanName已注册依赖于dependentBeanName的关系if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// 注册各个bean的依赖关系,方便进行销毁registerDependentBean(dep, beanName);try {// 递归优先实例化被依赖的BeangetBean(dep);}// 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance.// 创建bean的实例对象if (mbd.isSingleton()) {// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:sharedInstance = getSingleton(beanName, () -> {try {// 为给定的合并后BeanDefinition(和参数)创建一个bean实例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.// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除// 接收到该Bean临时引用的任何Bean// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBeandestroySingleton(beanName);// 重新抛出exthrow ex;}});// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}// 原型模式的bean对象创建else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.// 它是一个原型 -> 创建一个新实例// 定义prototype实例Object prototypeInstance = null;try {// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中beforePrototypeCreation(beanName);// 为mbd(和参数)创建一个bean实例prototypeInstance = createBean(beanName, mbd, args);}finally {// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除afterPrototypeCreation(beanName);}// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {// 指定的scope上实例化beanString scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}// 从scopes中获取scopeName对于的Scope对象Scope scope = this.scopes.get(scopeName);// 如果scope为nullif (scope == null) {// 抛出非法状态异常:没有名为'scopeName'的scope注册throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {// 从scope中获取beanName对应的实例对象Object scopedInstance = scope.get(beanName, () -> {// 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中beforePrototypeCreation(beanName);try {// 为mbd(和参数)创建一个bean实例return createBean(beanName, mbd, args);}finally {// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除afterPrototypeCreation(beanName);}});// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {// 捕捉非法状态异常// 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此// beanDefinition一个作用域代理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);}}}catch (BeansException ex) {// 捕捉获取Bean对象抛出的Bean异常// 在Bean创建失败后,对缓存的元数据执行适当的清理cleanupAfterBeanCreationFailure(beanName);// 重新抛出exthrow ex;}}// Check if required type matches the type of the actual bean instance.// 检查requiredType是否与实际Bean实例的类型匹配// 如果requiredType不为null&&bean不是requiredType的实例if (requiredType != null && !requiredType.isInstance(bean)) {try {// 获取此BeanFactory使用的类型转换器,将bean转换为requiredTypeT convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);// 如果convertedBean为nullif (convertedBean == null) {// 抛出Bean不是必要类型的异常throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}// 返回convertedBeanreturn convertedBean;}catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {logger.trace("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}// 将bean返回出去return (T) bean;}

详细说明:doGetBean

03.这一段:上一章详细说过,就是害怕出现别名

	// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx// name有可能传入进来的是别名,那么beanName就是idString beanName = transformedBeanName(name);Object beanInstance;

04.这一段:getSingleton从缓存中获取单例,上一章写过三级缓存

// 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 + "'");}}// 如果sharedInstance是FactoryBean,那么就调用getObject()返回对象beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}

其中的getObjectForBeanInstance方法:为了防止传入的是FactoryBean类,那么要用这个FactoryBean类重写的方法getObject方法来获取真正的对象

	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.// 如果参数name是&xxx,那么就直接返回单例池中的对象  Bean的name如果以“&”开头,说明是想获得FactoryBean本身if (BeanFactoryUtils.isFactoryDereference(name)) {if (beanInstance instanceof NullBean) {return beanInstance;}if (!(beanInstance instanceof FactoryBean)) {//没有实现FactoryBean接口throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());}if (mbd != null) {//实现FactoryBean接口  将RootBeanDefinition 中的isFactoryBean 设置为truembd.isFactoryBean = true;}return beanInstance;}// 现在拥有了一个新的 BeanInstance, 这个实例可能是常规 Bean 也有可能是 FactoryBean<?>// 如果是 FactoryBean<?> 则使用它创建实例, 但如果是开发者想要直接获取工厂实例而不是工厂的 getObject()// 方法对应的实例, 那么传入的 BeanName 应该加入前缀 '&'// 单例池中的对象不是FactoryBean,则直接返回if (!(beanInstance instanceof FactoryBean)) {return beanInstance;}
//此时参数的name是factoryBean的name,但是没有以&开头,就代表要用getObjectObject object = null;if (mbd != null) {mbd.isFactoryBean = true;}else {// 从factoryBeanObjectCache中直接拿对象object = getCachedObjectForFactoryBean(beanName);}// 此时factoryBeanObjectCache中没有这个对象// 激活 FactoryBean<?> 的 getObject() 方法if (object == null) {// Return bean instance from factory.// 这里已经明确知道 beanInstance 一定是 FactoryBean<?> 类型FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.if (mbd == null && containsBeanDefinition(beanName)) {// 将BeanDefinition 转换为 RootBeanDefinition, 如果指定的 BeanName// 是子 Bean 的话同时会合并父类的相关属性mbd = getMergedLocalBeanDefinition(beanName);}// synthetic为true,表示这个Bean不是正常的一个Bean,可能只是起到辅助作用的,所以这种Bean就不用去执行PostProcessor了boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}

其中开始的BeanFactoryUtils.isFactoryDereference(name):

这里用的变量是 String FACTORY_BEAN_PREFIX = “&”;

	public static boolean isFactoryDereference(@Nullable String name) {//也就是判断name是不是null并且以&开头,都是对的,返回turereturn (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));}

其二.最后的containsBeanDefinition方法,判断是不是有beanName对应的BeanDefinition

	@Overridepublic boolean containsBeanDefinition(String beanName) {Assert.notNull(beanName, "Bean name must not be null");return this.beanDefinitionMap.containsKey(beanName);}

其二.最后用到的getObjectFromFactoryBean方法:

	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {// 如果是单例 Bean && Bean 实例已经创建过, 没有再次创建的必要, 要保证单例 Bean 全局唯一, 直接从缓存中获取if (factory.isSingleton() && containsSingleton(beanName)) {// 进入同步代码块synchronized (getSingletonMutex()) {// 从缓存中获取Object object = this.factoryBeanObjectCache.get(beanName);// 如果缓存中没有if (object == null) {// 激活 FactoryBean<?> 中的 getObject() 方法获取开发者// 定制的初始化逻辑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)Object alreadyThere = this.factoryBeanObjectCache.get(beanName);if (alreadyThere != null) {object = alreadyThere;}else {if (shouldPostProcess) {if (isSingletonCurrentlyInCreation(beanName)) {// Temporarily return non-post-processed object, not storing it yet..return object;}beforeSingletonCreation(beanName);try {object = postProcessObjectFromFactoryBean(object, beanName);}catch (Throwable ex) {throw new BeanCreationException(beanName,"Post-processing of FactoryBean's singleton object failed", ex);}finally {afterSingletonCreation(beanName);}}if (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;}}

其中的doGetObjectFromFactoryBean():就是一个factory.getObject()

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {Object object;try { if (System.getSecurityManager() != null) {AccessControlContext acc = getAccessControlContext();try {object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);}catch (PrivilegedActionException pae) {throw pae.getException();}}else {// 激活 FactoryBean<?> 中的 getObject() 方法调用// 开发者定制化的的 Bean 注册逻辑object = factory.getObject();}}catch (FactoryBeanNotInitializedException ex) {throw new BeanCurrentlyInCreationException(beanName, ex.toString());}catch (Throwable ex) {throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);}// Do not accept a null value for a FactoryBean that's not fully// initialized yet: Many FactoryBeans just return null then.if (object == null) {if (isSingletonCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");}object = new NullBean();}return object;}

05.回到dogetbean方法:如果单例池里面没有,这里进入else部分

isPrototypeCurrentlyInCreation和循环依赖有关,暂时不管

getParentBeanFactory 和springmvc有关,也暂时不管

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.// 如果bean定义不存在,就检查父工厂是否有BeanFactory parentBeanFactory = getParentBeanFactory();// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】String nameToLookup = originalBeanName(name);// 如果父工厂是AbstractBeanFactory的实例if (parentBeanFactory instanceof AbstractBeanFactory) {// 调用父工厂的doGetBean方法,就是该方法。【递归】return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.// 如果有创建bean实例时要使用的参数// Delegation to parent with explicit args. 使用显示参数委派给父工厂// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型return parentBeanFactory.getBean(nameToLookup, requiredType);}else {// 使用父工厂获取bean,通过bean全类名return (T) parentBeanFactory.getBean(nameToLookup);}}

06.else的下一个部分:还是在else部分

主要看 getDependsOn 这里涉及@Dependon 注解
例子:
UserService 在创建bean之前要创建User的bean才可以

@Component
@DependsOn("User")
public class UserService  {}

那如果:User 类有注解@DependsOn(“OrderService”)
User 在创建bean之前要创建OrderService的bean才可以

@Component
@DependsOn("OrderService")
public class User  {}

如果出现:
一个类 A 有注解@DependsOn(“B”)
一个类 B 有注解@DependsOn(“A”)

则叫做A,B两个类的循环依赖

else的具体代码:

			// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录if (!typeCheckOnly) {// 为beanName标记为已经创建(或将要创建)markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查BeanDefinition是不是Abstract的checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了for (String dep : dependsOn) {// beanName是不是被dep依赖了,如果是则出现了循环依赖if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为valueregisterDependentBean(dep, beanName);// 创建所依赖的beantry {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}

checkMergedBeanDefinition方法:

	protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)throws BeanDefinitionStoreException {if (mbd.isAbstract()) {throw new BeanIsAbstractException(beanName);}}

getDependsOn方法:

@Nullable
private String[] dependsOn;public String[] getDependsOn() {return this.dependsOn;
}

07.else的继续:这里判断注解Scope的值 创建几个bean

用到的一个map:

	private final Map<String, Scope> scopes = new LinkedHashMap<>(8);
// Create bean instance.// 创建bean的实例对象if (mbd.isSingleton()) {// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:sharedInstance = getSingleton(beanName, () -> {try {// 为给定的合并后BeanDefinition(和参数)创建一个bean实例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.// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除// 接收到该Bean临时引用的任何Bean// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBeandestroySingleton(beanName);// 重新抛出exthrow ex;}});// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}// 原型模式的bean对象创建else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.// 它是一个原型 -> 创建一个新实例// 定义prototype实例Object prototypeInstance = null;try {// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中beforePrototypeCreation(beanName);// 为mbd(和参数)创建一个bean实例prototypeInstance = createBean(beanName, mbd, args);}finally {// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除afterPrototypeCreation(beanName);}// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {// 指定的scope上实例化beanString scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}// 从scopes中获取scopeName对于的Scope对象Scope scope = this.scopes.get(scopeName);// 如果scope为nullif (scope == null) {// 抛出非法状态异常:没有名为'scopeName'的scope注册throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {// 从scope中获取beanName对应的实例对象Object scopedInstance = scope.get(beanName, () -> {// 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中beforePrototypeCreation(beanName);try {// 为mbd(和参数)创建一个bean实例return createBean(beanName, mbd, args);}finally {// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除afterPrototypeCreation(beanName);}});// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {// 捕捉非法状态异常// 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此// beanDefinition一个作用域代理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);}}}catch (BeansException ex) {// 捕捉获取Bean对象抛出的Bean异常// 在Bean创建失败后,对缓存的元数据执行适当的清理cleanupAfterBeanCreationFailure(beanName);// 重新抛出exthrow ex;}}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/3434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目十:学会python爬虫数据保存(小白圆满级)

前言 上篇我们学会的文本文件、csv文件和excel文件的相关基础知识和操作&#xff0c;这一次我们再来了解一下四个文件操作方式 存储方法 HTML文件 将数据保存为HTML格式&#xff0c;可以直接在浏览器中查看。 使用字符串拼接将数据保存为HTML格式。 代码案例 # 创建数据…

Cookie、Session以及Token的区别

Cookei、Session以及Token总的来说都是为了实现客户端访问服务器数据而利用的一种手段&#xff0c;可以把服务器数据看成是密码箱&#xff0c;而它们是三种不同的钥匙。 一、定义 1.Cookie 客户端第一次访问服务器时&#xff0c;服务器返回cookie给客户端A&#xff0c;客户端…

ABTest如何计算最小样本量-工具篇

如果是比例类指标&#xff0c;有一个可以快速计算最小样本量的工具&#xff1a; https://www.evanmiller.org/ab-testing/sample-size.html 计算样本量有4个要输入的参数&#xff1a;①一类错误概率&#xff0c;②二类错误概率 &#xff08;一般是取固定取值&#xff09;&…

第 394 场 LeetCode 周赛题解

A 统计特殊字母的数量 I 哈希&#xff1a;遍历然后枚举 class Solution {public:int numberOfSpecialChars(string word) {unordered_map<char, int> m;for (auto ch : word)m[ch] 1;int res 0;for (char ch a; ch < z; ch)if (m.count(ch) && m.count(A …

【SpringCloud】OpenFeign高级特性

【SpringCloud】OpenFeign高级特性 文章目录 【SpringCloud】OpenFeign高级特性1. 超时控制1.1 全局配置1.2 指定配置 2. 重试机制3. 替换Http客户端3.1 引入依赖3.2 配置 4. 请求/响应压缩5. 日志打印6. 综合配置 1. 超时控制 默认OpenFeign客户端等待60秒钟&#xff0c;但是服…

8.4.1 实验1:创建 VLAN 和划分端口

1、实验目的 通过本实验可以掌握&#xff1a; VLAN的概念。创建VLAN的方法。把交换机端口划分到VLAN中的方法。 2、实验拓扑 创建 VLAN 和划分端口的实验拓扑如下图所示。 图8-5 创建 VLAN 和划分端口的实验拓扑 3、实验步骤 &#xff08;1&#xff09;实验准备 S1#eras…

创建一个空的maven项目,整合SpringBoot和Redis

创建一个空的maven项目&#xff0c;整合SpringBoot和Redis 创建空的maven项目 在最新版的idea中创建maven项目的时候会让选择模板 如下图&#xff1a; 我们选择quickstart快速开始模板&#xff0c;quickstart快速开始模板创建的maven项目里面什么都不带&#xff0c;只有一个…

苹果手机里的HEIC图片可以转换成普通的JPG格式吗?什么是HEIC图片格式?

在现代社会中&#xff0c;随着智能手机技术的不断发展&#xff0c;我们越来越依赖于手机来记录生活的点滴。其中&#xff0c;拍照成为了人们记录生活的重要手段之一。苹果手机作为市场上的热门品牌&#xff0c;其拍摄的照片质量自然也是备受赞誉。然而&#xff0c;苹果手机默认…

Java面试八股之Java中==和equals()的区别

Java中和equals()的区别 操作符&#xff1a; 对于基本数据类型&#xff08;如int、char、boolean等&#xff09;&#xff0c;比较的是它们的值是否相等。 对于对象引用类型&#xff0c;比较的是两个对象的内存地址&#xff08;即是否指向同一个对象实例&#xff09;。也就是…

4.25日学习记录

[HZNUCTF 2023 preliminary]ppppop 对于php反序列化&#xff0c;在之前的学习中有过了解&#xff0c;但是对于序列化字符串的格式不是很了解&#xff0c;刚好接触这题&#xff0c;可以了解一下 序列化字符串的格式&#xff1a; 布尔型&#xff08;bool&#xff09;b&#xf…

ubuntu20.04开机运行java的sh脚本

用到了 rc.local 1、修改 /usr/lib/systemd/system/rc-local.service 在最下面添加 [Install] WantedBymulti-user.target 2、 系统没有 rc.local&#xff0c;需要手动创建 cd /etc vi rc.local在里面写入 /opt/start.sh chmod x /etc/rc.local # 添加可执行权限 chmod x…

基于小程序实现的惠农小店系统设计与开发

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

队列的实现(c语言实现)

队列的定义 队列&#xff08;Queue&#xff09;是一种特殊的线性数据结构&#xff0c;它遵循先进先出&#xff08;FIFO&#xff0c;First In First Out&#xff09;的原则。这意味着最早被添加到队列中的元素将是最先被移除的元素。队列的主要操作包括入队&#xff08;enqueue…

【错题集-编程题】数组中的最长连续子序列(排序 + 模拟)

牛客对应链接&#xff1a;数组中的最长连续子序列_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 排序 模拟。 注意&#xff1a;值连续&#xff0c;位置可以不连续&#xff01;小心处理数字相同的情况。 二、代码 //值得学习的代码 class Solution { public:int MLS(vecto…

数字藏品:重塑艺术与科技的新媒介

数字藏品&#xff0c;这个新兴的词汇&#xff0c;正在逐渐渗透到我们的日常生活中。它不仅是一种新的艺术表达方式&#xff0c;更是一种科技与艺术相结合的全新媒介。那么&#xff0c;数字藏品究竟是什么呢&#xff1f; 首先&#xff0c;我们需要明确一点&#xff0c;数字藏品并…

LeetCode53. 最大子数组和

LeetCode53. 最大子数组和 解题思路dp 代码 /* 数组长度n 9,连续的区间 那区间长度为1的区间数量是&#xff0c;9个 区间长度为2的区间数量是8个 区间长度为3的连续的区间数量为7个 .... 区间长度为9的区间数量为1个 */ class Solution { public:int maxSubArray(vector<…

游戏工作室为什么要使用海外住宅IP防封?

当谈到游戏工作室时&#xff0c;它们通常以多开游戏账号来获取收益为主要目标。这种商业模式在游戏产业中已经成为一个独特而且颇具潜力的领域。然而&#xff0c;随之而来的是防封问题&#xff0c;特别是当游戏工作室试图通过多开账号来赚取更多收益时。因此&#xff0c;我们有…

13(第十二章,元数据管理)

目录 概述 业务驱动因素 目标和原则 基本概念 元数据与数据 元数据的类型 业务元数据 技术元数据 操作元数据 元数据注册标准 元数据来源 元数据架构类型 集中式元数据架构 分布式元数据架构 混合式元数据架构 双向元数据架构 方法 数据血缘和影响分析 度量…

Java操作 elasticsearch 8.1,如何实现索引的重建?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

U盘无法正常格式化?教你一个强力的办法

前言 电脑格式化U盘或者移动硬盘的操作&#xff0c;相信各位小伙伴都是有一定经历的。 如果设备正常&#xff0c;那么进入到【此电脑】&#xff0c;在对应的分区点击【鼠标右键】-【格式化】就可以把对应的存储设备恢复到初始状态。 但凡事都会有例外&#xff0c;比如在格式化…