iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >spring如何获取bean的源码解析
  • 126
分享到

spring如何获取bean的源码解析

2023-06-14 21:06:13 126人浏览 独家记忆
摘要

这篇文章主要介绍了spring如何获取bean的源码解析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。源码直接看源码吧@Overridepublic Object&

这篇文章主要介绍了spring如何获取bean的源码解析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

源码

直接看源码吧

@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);} @Overridepublic <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);} @Overridepublic Object getBean(String name, Object... args) throws BeansException {return doGetBean(name, null, args, false);}  public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)throws BeansException { return doGetBean(name, requiredType, args, false);}  @SuppressWarnings("unchecked")protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {                // 把name转化成beanName,也就是把FactoryBean的名称转化成beanName如果有别名则用别名final String beanName = transfORMedBeanName(name);Object bean; // 从缓存中获取实例        // 可能是需要的Bean实例,也可能是FactoryBeanObject sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}            // 获取需要的bean或者FactoryBeanbean = getObjectForBeanInstance(sharedInstance, name, beanName, null);} else {// 判断prototype类型的bean是否存在循环引用if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);} // 校验父类BeanFactoryBeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// 父类去获取beanString 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 {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}}                        // 标记成已创建if (!typeCheckOnly) {markBeanAsCreated(beanName);} try {                // 把原来BeanDefinition转换成RootBeanDefinitionfinal RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args); // 获取依赖的bean,也就是通过@DependsOn注入进来的beanString[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {                        // 校验dependsOn的bean是否存在循环应用if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}                        // 加入到引用的缓存中,由于校验dependsOn循环引用reGISterDependentBean(dep, beanName);                        // 获取@dependsOn的beangetBean(dep);}} // 创建单例的beanif (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或者FactoryBeanbean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}                // 创建prototype的beanelse 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);}                // 创建其他的bean,比如session,request等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);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}} // 如果要求的类型不是这个bean的实例类型,则进行转换if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return convertedBean;}catch (TypeMismatchException ex) {if (logger.isDebugEnabled()) {logger.debug("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}

获取bean的整体流程就像上面源码所示,这里再梳理下spring获取bean的整个流程

先转换bean的名称,转换成beanName。这里意思就是,我们在获取bean的时候,可能是FactoryBean的名称(&开头),这里转成不带&开头的名称,如果有别名,再获取别名。

从缓存中获取bean,这里的缓存分为一二三级缓存,也就是我们常常被问到了spring三级缓存,具体逻辑下面再说。

根据获取的到对象再去获取我们想要的bean,因为这里获取到的对象可能是我们需要的bean,也可能是FactoryBean。

如果缓存中没有,那么我们就要自己去创建bean了。

查看有没有父类的BeanFactory,如果有,那么就父类去创建bean。

获取要创建的bean对象的@DependsOn注解上的名称,先去创建DependsOn的bean,并且校验是否存在循环引用

创建bean,根据类型创建不同的bean,比如singleton,prototype,request,session等。

如果需要转换类型,则进行类型转换。

整体的获取bean的流程就是这样了,其中有些具体流程接着分析。

从缓存中获取bean对象

public Object getSingleton(String beanName) {return getSingleton(beanName, true);}  @Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {        // 从一级缓存中获取Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {                // 从二级缓存中获取singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {                    // 从三级缓存中获取ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;}

spring通过三级缓存来解决循环依赖的问题。简单来介绍下三级缓存。

 singletonObjects为一级缓存,我们实例化的bean都在这个map里,侠义的说singletonObjects才是我们真正的spring容器,存放bean的地方。

earlySingletonObjects为二级缓存,是存放未完成的bean的缓存,如果有代理的话,存放的是代理对象。

singletonFactories为三级缓存,存放的是一个ObjectFactory,数据通过getObject方法获得。

从BeanInstance中获取对象

接下来看getObjectForBeanInstance方法。

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {         // name是不是factoryBean的name(&开头的)if (BeanFactoryUtils.isFactoryDereference(name)) {if (beanInstance instanceof NullBean) {return beanInstance;}            // 如果是FactoryBeanName,但是获取到的bean不是FactoryBean,则抛异常if (!(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());}}         // 如果bean不是FactoryBean,或者名称是FactoryBeanName,直接返回BeanInstaceif (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;} Object object = null;if (mbd == null) {            // 从缓存中获取object = getCachedObjectForFactoryBean(beanName);}if (object == null) {// 这里可以确定beanInstance是FactoryBean了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());            // 通过FactoryFBean中获取需要的beanInstanceobject = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}

这里是通过BeanInstance获取我们想要的bean,这里也简单说下流程

首先判断name是不是FactoryBean的name,也就是&开头的name,如果是去判断beanInstance是不是FactoryBean,如果beanInstance不是FactoryBean则抛异常。

由于上面已经判断过,如果name是FactoryBeanName,但是BeanInstance不是FactoryBean的话,就会抛出异常。所以如果BeanInstance如果不是FactoryBean的话,那么name一定不是FactoryBeanName。那么就直接返回BeanInstance就是我们需要的了。

如果name是FactoryBeanName,那么我们需要获取的就是FactoryBean,也直接返回就可以了。

如果都没有返回,那么已经可以确定我们此时的已经可以确定BeanInstance是FactoryBean了,因为如果不是FactoryBean的话,在!(beanInstance instanceof FactoryBean)就已经返回了。

通过FactoryBean的getObject方法获取我们需要的bean实例。

创建bean

根据@dependsOn查找依赖的bean并且加到依赖里面去没有什么好说的,代码逻辑也很简单,接下来看创建单例bean。其他类型的bean的创建也都差别不大。看源码

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 + "'");}                // 在没创建bean之前的处理beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {                    // 获取创建的beansingletonObject = 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;}}

对于创建单例bean的主要流程就是如此,传入一个beanName,和一个ObjectFactory。ObjectFactory中具体实现了创建bean的逻辑。在看具体创建bean的逻辑之前,我们还需要去看下getSingleton中的创建bean之前的工作和创建bean之后的工作。这里面就是查找bean的循环依赖的方法(和dependsOn不同)。主要是查找根据filed,set,构造器方法的循环依赖。

protected void beforeSingletonCreation(String beanName) {if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}} protected void afterSingletonCreation(String beanName) {if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");}}

可以看到代码非常的简单,就是创建bean之前,如果没有排除依赖检查,那么就加入到正在创建的Set中,如果加入不进去,说明之前已经加过,这就产生了循环依赖,从而抛出异常。

如果在创建bean之后,没有排除检查依赖,并且移除失败,说明已经不在Set中,也会抛出异常。

好了,既然明白了spring是如何校验循环依赖的,也看到了三级缓存,后面再说为什么不能解决构造器依赖就很好说了。接着看创建bean的方法。

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException { if (logger.isDebugEnabled()) {logger.debug("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;                // 获取要创建bean的classClass<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {            // 如果没有beanclass,设置beanclaSSMbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);} // 配置方法重载try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);} try {// 那些beanPostProcessor如果能产生代理,则直接返回beanObject bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);} try {            // 创建beanObject beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) {logger.debug("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException ex) {// A previously detected exception with proper bean creation context already...throw ex;}catch (ImplicitlyAppearedSingletonException ex) {// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}

这里其实还是没有到创建bean的过程,还是在创建bean的一些准备工作。其实我们可以发现,spring中,真正做事的都是do开头的方法。

这边的流程就是设置beanClass,后面需要根据反射来创建bean。然后会根据spring里面的beanPostProcessor,看看有没有能产生代理bean的,如果有就返回,没有就去创建bean。

看真正的doCreateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException { // 装饰Bean的对象BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {            // 通过缓存获取instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {            // 创建beaninstanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;} // Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {                    // 调用MergedBeanDefinitionPostProcessor的方法applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}} // 加入到三级缓存中去boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isDebugEnabled()) {logger.debug("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));} // Initialize the bean instance.Object exposedObject = bean;try {            // 填充依赖的bean,field注入,和方法注入的beanpopulateBean(beanName, mbd, instanceWrapper);            // 调用初始化的方法exposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}} if (earlySingletonExposure) {            // 获取二级缓存的值Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {                // 如果一致,则直接使用二级缓存的对象if (exposedObject == bean) {exposedObject = earlySingletonReference;}                // 如果调用初始化后的bean和之前的bean不一致,并且有依赖else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {                    // 查找循环依赖String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {                        // 如果有循环依赖并且在创建中,则抛出异常if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}} // 注册disposableBeantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);} return exposedObject;}

真正创建bean这里还是有点复杂的。这里再进行一个简单梳理。

根据class还有bean以及参数创建bean。

调用beanPostprocessor的方法,调用属于MergedBeanDefinitionPostProcessor的方法。对bean进行一些处理,比如找到那些依赖的bean的field和method。

将bean加入到三级缓存中去。

填充bean需要注入的其他bean。

调用初始化方法,先去调用@PostConstruct注解方法,然后调用InitializingBean的afterPropertiesSet,以及自定义的init-method方法。在bean调用初始化方法之后,再去调用后置接口看看是否需要生成aop代理。

接着进行校验。这里稍微比较复杂一点。如果从二级缓存能取到,那就说明之前被别人从三级缓存拿出来过了。可能是因为循环依赖,也可能是因为别的地方调用了getBean方法了。从三级缓存拿出来的时候有个getEarlyBeanReference的方法,就是查看是否要生成代理的bean。如果生成过了,那么在调用第五步的时候,就不会在生成代理了。这样exposedObject ==bean,直接只用代理返回。

如果不相等:这里的情况就是如果是spring自己的@Async,在从二级缓存生成代理之后,再去调用第五步时候一样会生成代理。所以exposedObject !=bean,所以在再往下发现有循环调用,并且bean还在创建时,就会抛出异常了。所以一般慎用spring的@Async。但是一般也可以使用@Lazy进行处理。至于原理后面再说。

到这里spring的创建bean就结束了。然后返回时候就到了入口方法getBean的getObjectForBeanInstance的方法,到底需要的bean还是FactoryBean。

最后就是如果requiredType和实例不一样就要进行类型转换了。

感谢你能够认真阅读完这篇文章,希望小编分享的“spring如何获取bean的源码解析”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

--结束END--

本文标题: spring如何获取bean的源码解析

本文链接: https://www.lsjlt.com/news/274957.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • spring如何获取bean的源码解析
    这篇文章主要介绍了spring如何获取bean的源码解析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。源码直接看源码吧@Overridepublic Object&...
    99+
    2023-06-14
  • spring获取bean的源码解析
    介绍 前面一章说了AbstractApplicationContext中的refresh方法中的invokeBeanFactoryPostProcessors。主要是调用BeanFa...
    99+
    2024-04-02
  • Spring源码解析Bean的实例化
    目录前言准备工作实例化bean1、AbstractBeanFactory 的 doGetBean方法2、AbstractAutowireCapableBeanFactory 的 cr...
    99+
    2024-04-02
  • Spring源码剖析3:懒加载的单例Bean获取过程分析
    spring ioc 容器的加载流程...
    99+
    2023-06-02
  • Spring源码解析Bean属性填充
    目录前言属性填充执行回调方法及后置处理器前言 在上一篇文章中,我们分析了Spring中Bean的实例化过程,在结尾我们知道了虽然bean的实例化完成了,但是其中的属性还没有被注入,今...
    99+
    2024-04-02
  • Spring源码解析之Bean的生命周期
    一、Bean的实例化概述 前一篇分析了BeanDefinition的封装过程,最终将beanName与BeanDefinition以一对一映射关系放到beanDefinitionMa...
    99+
    2024-04-02
  • 浅析Spring获取Bean的九种方法详解
    目录前言Spring的IoC容器BeanFactory与ApplicationContext的区别通过BeanFactory获取通过BeanFactoryAware获取启动获取App...
    99+
    2023-01-28
    Spring获取Bean方法 Spring Bean获取方法
  • Spring中Bean注入源码示例解析
    目录BeanDefinition和BeanBeanDefinition的注入BeanDefinitionRegistry接口BeanDefinitionRegistry的实现类Sim...
    99+
    2023-01-15
    Spring Bean注入 Spring源码解析
  • 如何获取所有spring管理的bean
    目录获取所有spring管理的beanIOC容器使用ListableBeanFactory接口使用Spring Boot Actuator小结一下spring管理bean的原理使用s...
    99+
    2024-04-02
  • MyBatis3源码解析之如何获取数据源详解
    目录前言jdbc传统JDBC弊端思考源码分析获取数据源总结前言 上文讲的MyBatis部署运行且根据官网运行了一个demo:一步到位部署运行MyBatis3源码<保姆级>...
    99+
    2024-04-02
  • 带你了解Spring中bean的获取
    目录Spring 中bean的获取总结Spring 中bean的获取 1.通过context.getbean 的方式来获取bean ApplicationContext:是spri...
    99+
    2024-04-02
  • Spring Bean生命周期源码分析
    这篇“Spring Bean生命周期源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring ...
    99+
    2023-07-05
  • Spring@Bean注解深入分析源码执行过程
    目录AnnotationConfigApplicationContext创建创建AnnotatedBeanDefinitionReader和ClassPathBeanDefiniti...
    99+
    2023-01-10
    Spring @Bean注解 Spring @Bean Spring @Bean源码
  • MyBatis源码解析——获取SqlSessionFactory方式
    目录MyBatis源码解析_获取SqlSessionFactory首先从Resources.getResourceAsReader(path)进入到SqlSessionFactory...
    99+
    2024-04-02
  • 关于Spring源码是如何解决Bean的循环依赖
    目录两个单例testA testB 互相依赖的实例化过程Spring容器创建单例“testA”beanSpring容器创建单例“testB”bean源码中的实现方式首先了解一下创建B...
    99+
    2024-04-02
  • MyBatis3源码解析之怎么获取数据源
    这篇文章主要讲解了“MyBatis3源码解析之怎么获取数据源”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MyBatis3源码解析之怎么获取数据源”吧!jdbc再贴一个JDBC运行的测试方法...
    99+
    2023-07-02
  • 利用JSP 如何实现获取spring容器中的bean
    这篇文章给大家介绍利用JSP 如何实现获取spring容器中的bean,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。JSP 获取spring容器中bean的方法总结方案1(Web中使用):ApplicationCont...
    99+
    2023-05-31
    jsp spring bean
  • Spring获取Bean的过程是怎样的
    这篇文章主要讲解了“Spring获取Bean的过程是怎样的”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring获取Bean的过程是怎样的”吧!原型Bean加载过程之前的文章,分析了非懒...
    99+
    2023-06-02
  • 如何获取gitee的开源代码
    在当今的软件开发领域中,开源成为了一种趋势,许多软件开发者都在积极地将自己的作品开源。开源维护网站也因此应运而生,gitee便是其中之一。gitee作为国内知名的代码托管网站,为开发者提供丰富的开源项目资源。如何获取gitee的开源代码?下...
    99+
    2023-10-22
  • Spring Bean获取方式的实例化方式详解
    目录1.通过构造方法实例化2.通过简单工厂模式实例化3.通过factory-bean实例化4.通过FactoryBean接口实例化5.BeanFactory和FactoryBean的...
    99+
    2023-03-09
    Spring获取bean的方式 Spring Bean获取方式
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作