日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java获取当前周一_Java互联网架构-Spring IOC源码分析

發布時間:2025/3/15 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java获取当前周一_Java互联网架构-Spring IOC源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

歡迎關注頭條號:java小馬哥

周一至周日下午三點半!精品技術文章準時送上!!!

精品學習資料獲取通道,參見文末

源碼介紹之前,看幾個問題:

  • Bean的承載對象是什么?
  • Bean的定義如何存儲的?
  • Bean工廠是如何生產bean的?
  • Bean的依賴關系由誰來解決?
  • Bean工廠和ApplicationContext的區別?

Bean的構建過程

spring.xml文件中保存了我們對Bean的描述配置,BeanFactory會讀取這些配置然后生成對應的Bean。

這些配置信息最后由BeanDefinition來承載。

BeanDefinition(Bean定義)

IOC實現中,我們在xml中的描述的Bean信息最后都將保存至BeanDefinition對象中,其中xml bean與BeanDefinition是一對一的關系。

xml bean的屬性配置與BeanDefinition對應關系

XML-Bean BeanDefinition class beanClassName scope SCOPE_SINGLETON、SCOPE_PROTOTYPE lazy-init AbstractBeanDefinition.lazyInit constructor-arg AbstractBeanDefinition.ConstructorArgument property AbstractBeanDefinition.propertyValues factory-method AbstractBeanDefinition.factoryMethondName destroy-method AbstractBeanDefinition.destroyMethodName init-method AbstractBeanDefinition.initMethodName autowire AbstractBeanDefinition.autowireMode id name BeanDefinition.java

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; ...}

AbstractBeanDefinition.java

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { public static final String SCOPE_DEFAULT = ""; public static final int AUTOWIRE_NO = 0; public static final int AUTOWIRE_BY_NAME = 1; public static final int AUTOWIRE_BY_TYPE = 2; public static final int AUTOWIRE_CONSTRUCTOR = 3; /** @deprecated */ @Deprecated public static final int AUTOWIRE_AUTODETECT = 4; public static final int DEPENDENCY_CHECK_NONE = 0; public static final int DEPENDENCY_CHECK_OBJECTS = 1; public static final int DEPENDENCY_CHECK_SIMPLE = 2; public static final int DEPENDENCY_CHECK_ALL = 3; public static final String INFER_METHOD = "(inferred)"; private volatile Object beanClass; private String scope; private boolean abstractFlag; private boolean lazyInit; private int autowireMode; private int dependencyCheck; private String[] dependsOn; private boolean autowireCandidate; private boolean primary; private final Map qualifiers; private boolean nonPublicAccessAllowed; private boolean lenientConstructorResolution; private String factoryBeanName; private String factoryMethodName; private ConstructorArgumentValues constructorArgumentValues; private MutablePropertyValues propertyValues; private MethodOverrides methodOverrides; private String initMethodName; private String destroyMethodName; private boolean enforceInitMethod; private boolean enforceDestroyMethod; private boolean synthetic; private int role; private String description; private Resource resource; ...}

BeanDefinitionRegistry(Bean注冊器)

在上面沒有看到xml bean中的id、name屬性對應在bean定義中,原因是id其作為當前bean的存儲key注冊到BeanDefinitionRegistry注冊器中。name作為別名key注冊到AliasRegistry注冊中心。其最后都是指向對象的BeanDefinition。

BeanDefinitionRegistry.java

public interface BeanDefinitionRegistry extends AliasRegistry { void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException; void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException; boolean containsBeanDefinition(String var1); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); boolean isBeanNameInUse(String var1);}

AliasRegistry.java

public interface AliasRegistry { void registerAlias(String var1, String var2); void removeAlias(String var1); boolean isAlias(String var1); String[] getAliases(String var1);}

BeanDefinitionReader(Bean定義讀取)

前面知道了BeanDefinition存儲了xml bean信息,而BeanDefinitionRegistry基于id和name保存bean的定義,下面是xml bean到BeanDefinition然后注冊到BeanDefinitionRegistry整個過程。

分為3步:

1、BeanDefinitionReader讀取spring.xml

2、讀取后創建BeanDefinition

3、創建好后注冊到BeanDefinitionRegister

BeanDefinitionReader.java

public interface BeanDefinitionReader { //獲取注冊器 BeanDefinitionRegistry getRegistry(); //獲取資源裝載器 ResourceLoader getResourceLoader(); //獲取bean類加載器 ClassLoader getBeanClassLoader(); BeanNameGenerator getBeanNameGenerator(); //基于資源裝載Bean定義并注冊到注冊器 int loadBeanDefinitions(Resource var1) throws BeanDefinitionStoreException; int loadBeanDefinitions(Resource... var1) throws BeanDefinitionStoreException; //基于資源路徑裝載Bean定義并注冊到注冊器 int loadBeanDefinitions(String var1) throws BeanDefinitionStoreException; int loadBeanDefinitions(String... var1) throws BeanDefinitionStoreException;}

裝載過程demo

package com.demo.spring;import org.springframework.beans.factory.support.BeanDefinitionReader;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;import org.springframework.core.io.DefaultResourceLoader;import org.springframework.core.io.Resource;import java.util.Arrays;/** * com.demo.spring * * @author Zyy * @date 2019/2/13 11:34 */public class BeanDefinitionReaderTest { public static void main(String[] args) { //創建一個簡單注冊器 BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); //創建bean定義讀取器 BeanDefinitionReader reader = new XmlBeanDefinitionReader(registry); //創建資源讀取器 DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); //獲取資源 Resource resource = resourceLoader.getResource("spring.xml"); //裝載類定義 reader.loadBeanDefinitions(resource); //打印構建bean名稱 System.out.println(Arrays.toString(registry.getBeanDefinitionNames())); }}

運行結果

[di, driver, com.demo.spring.HelloSpring#0, com.demo.spring.LookUpTest#0, helloSpring, com.demo.spring.DI#1, com.demo.spring.DI#0, helloByName]

如果未給bean設置id則:class+#+索引,來標識id

com.demo.spring.HelloSpring#0

打印一下bean定義信息

spring.xml

打印語句:

System.out.println(registry.getBeanDefinition("di"));System.out.println(registry.getAliases("di2"));

結果信息:

Generic bean: class [com.demo.spring.DI]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=init; destroyMethodName=destroy; defined in class path resource [spring.xml][Ljava.lang.String;@73a28541

BeanFactory(bean工廠)

有了Bean的定義,則下面可以用BeanFactory來進行構建bean。

BeanFactory.java

public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; //基于id或name獲取一個bean Object getBean(String name) throws BeansException; //基于bean的類別獲取bean(如果出現多個該類的實例,則會報錯)但是可以指定primary="true"調整優先級來解決該報錯 T getBean(String name, Class requiredType) throws BeansException; T getBean(Class requiredType) throws BeansException; //基于名詞獲取一個bean,并覆蓋默認的構造參數 Object getBean(String name, Object... args) throws BeansException; T getBean(Class requiredType, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //指定bean與指定class是否匹配 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class> typeToMatch) throws NoSuchBeanDefinitionException; Class> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name);}

測試demo如下:

package com.demo.spring;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;import org.springframework.core.io.DefaultResourceLoader;/** * com.demo.spring * * @author Zyy * @date 2019/2/13 12:19 */public class BeanFactoryTest { public static void main(String[] args) { //注冊中心 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //讀取器 XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); //設置資源加載器 reader.setResourceLoader(new DefaultResourceLoader()); //裝載構建bean的定義 reader.loadBeanDefinitions("spring.xml"); //打印 System.out.println(beanFactory.getBean("di")); System.out.println(beanFactory.getBean("di2")); }}

當getBean時,看下堆棧信息,如下

at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) - locked <0x593> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at com.demo.spring.BeanFactoryTest.main(BeanFactoryTest.java:25)

看具體調用方法

instantiateClass:142, BeanUtils (org.springframework.beans)instantiate:89, SimpleInstantiationStrategy (org.springframework.beans.factory.support)instantiateBean:1147, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)createBeanInstance:1099, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)doCreateBean:513, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)main:25, BeanFactoryTest (com.demo.spring)

逐個點進去查看

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)@Overridepublic Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false);}

AbstractBeanFactory#getBean中繼續調用doGetBean,查看doGetBean,由于其中代碼太多,刪除檢查判斷,只保留核心代碼

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBeanprotected T doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //從單例緩存中獲取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // 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 (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 { // Create bean instance. //mbd -> RootBeanDefinition //判斷是否單例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { ... } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } 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, new ObjectFactory() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { ... } } } catch (BeansException ex) { ... } } return (T) bean;}

其中

Object sharedInstance = getSingleton(beanName);org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); //如果取到的為null且判斷是正在創建 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //則鎖住map synchronized (this.singletonObjects) { //從正在創建的earlySingletonObjects這個map中去取 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 != NULL_OBJECT ? singletonObject : null); }

其中singletonObjects、earlySingletonObjects、singletonFactories均是一個map

private final Map singletonObjects = new ConcurrentHashMap(256);private final Map earlySingletonObjects = new HashMap(16);private final Map> singletonFactories = new HashMap>(16);

對于其中的

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstanceif (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; }

其中如果是FactoryBean,則調用getObject()來獲取我們自定義的bean,例如

其中返回的不是DriverFactoryBean,而是返回Driver

public Class> getObjectType() { return Driver.class;}

總結:

1、調用BeanFactory.getBean()會觸發Bean的實例化。

2、DefaultSingletonBeanRegistry中緩存了單例Bean。

3、Bean的創建于初始化是由AbstractAutowireCapableBeanFactory完成的。

另外:

IOC容器只存放單例Bean,IOC容器在初始化的時候,會將所以Bean初始化在singletonObjects這個ConcurrentHashMap中。

在獲取bean的時候,首先會去singletonObjects中去取,如果scope是單例則可以獲取bean,如果是多例,則取不到bean,需要從mergedBeanDefinitions這個ConcurrentHashMap中獲取RootBeanDefinition,這個里面包含bean的基礎信息,然后判斷scope是prototype(多例),則每次都會創建一個新的實例。

對于@Autowire、@Resource等注解,在啟動SpringIOC容器時,容器會裝載一個AutowiredAnnotationBeanPostProcessor 后置處理器,當容易掃描到@Autowire、@Resource等注解時,就會在IOC容器中自動查找需要的Bean,并裝配給該對象的屬性,在使用@Autowire時,首先在容器中查詢對應類型的bean,如果查詢不止一個,則根據名稱來查,如果名稱沒有則拋異常,可以將required=false來解決,如果正好查詢到一個,則就將該bean裝配給@Autowire指定的變量。

對于bean之間相互引用的情況,比如A依賴B,B依賴A,這種情況時,先去實例化A,然后發現依賴B,接著去實例化B,如果此時發現B依賴A,容器會獲取A的一個早期引用(early reference),將這個早期引用的A注入給B,然后B實例化完了,則實例化A也就完成了。當然對于這種循環引用的代碼應該規避,這種不是正常的場景。

涉及的類:

BeanDefinition

DefaultResourceLoader

XmlBeanDefinitionReader

BeanDefinitionRegistry

BeanFactory

DefaultListableBeanFactory

AutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory

SingletonBeanRegistry

DefaultSingletonBeanRegistry

整個流程:

run->getBean->BeanFactory->doGetBean->AbstructBeanFactory->getSingleton(從緩存中獲取,如果是單例,為空則創建并緩存,如果是多例則直接創建)->DefaultSingleonBeanRegistry->createBean->AbstractAutowireCapableBeanFactory->createBeanInstance->newInstance->Constructor->反射實例化Bean

BeanFactory 與 ApplicationContext區別

看下結構圖

ApplicationContext.java

ApplicationContext.png

從圖中可以看到ApplicationContext是由BeanFactory接口派生出來的,具有BeanFactory所以功能。除此之外,還具有以下功能:

1、MessageSource,提供國際化的消息訪問

2、資源訪問,入url和文件

3、事件傳播,實現了ApplicationListener接口的bean

4、載入多個上下文(有繼承關系),使每個上下文都專注于一個特定的層次,比如應用web層

類似的

DefaultListableBeanFactory.java

封面圖源網絡,侵權刪除)

如有收獲,請幫忙轉發,您的鼓勵是作者最大的動力,謝謝!

一大波微服務、分布式、高并發、高可用的原創系列文章正在路上,

歡迎關注頭條號:java小馬哥

周一至周日早九點半!下午三點半!精品技術文章準時送上!!!

十余年BAT架構經驗傾囊相授

總結

以上是生活随笔為你收集整理的java获取当前周一_Java互联网架构-Spring IOC源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产一区二区在线精品 | 91麻豆蜜桃一区二区三区 | 色94色欧美sute亚洲线路二 | 偷偷操视频| 成人av影院 | 国产精品老牛影视 | 青青欧美| 玩弄人妻少妇500系列 | 午夜精品久久久久久久第一页按摩 | 久久久.www | 中文字幕超碰在线 | 亚洲免费黄色 | 91精品国产乱码久久久张津瑜 | 无码熟妇人妻av | 日韩电影在线观看一区二区 | 一色屋免费视频 | 黄色成年人 | av免费观看网 | 日韩一二三四 | 日本v片| 久久精品无码一区二区三区免费 | 波多野结衣黄色网址 | 亚洲经典久久 | 亚洲综合免费观看高清完整版在线 | 日韩欧美国产网站 | 成人精品一区二区三区四区 | 人人爱爱 | 国产免费999 | 嫩草视频在线观看视频 | 亚洲精品久久久久久无码色欲四季 | 亚洲午夜片 | 久久成人a毛片免费观看网站 | 日本性欧美 | 亚洲综合在线视频 | 少妇无内裤下蹲露大唇视频 | 亚洲一区二区三区四区五区六区 | 久久女同互慰一区二区三区 | 精品自拍av | 亚洲av无码久久精品狠狠爱浪潮 | 亚洲欧美日本一区二区 | 国产精品情侣自拍 | 狼色网 | 黄色尤物视频 | 成人h片 | 日婷婷 | 色吧av色av | 男女午夜视频在线观看 | 久久77 | 欧美精品欧美极品欧美激情 | 亚洲一区二区三区av无码 | 国产成人自拍视频在线观看 | 人妻洗澡被强公日日澡电影 | 中文字幕在线观看 | 国产av无码专区亚洲av麻豆 | 日韩精品一区二区三区免费视频 | 一本久久综合亚洲鲁鲁五月天 | 三年中文在线观看免费观看 | www.色国产| 视色网 | 亚洲精品字幕在线 | 国产精品高潮呻吟 | 亚洲欧美一区二区激情 | 国产美女福利在线 | 久久精品一区 | 日本不卡影院 | 男同互操gay射视频在线看 | 波多野结衣精品视频 | 免费黄色观看 | 色av一区 | 一区二区三区免费看 | 久久久久久av无码免费网站下载 | 最新中文字幕2019 | 天天躁日日躁aaaxxⅹ | www日本免费| 在线不卡一区二区 | 国产专区在线 | 激情啪啪网| 精品国产乱码久久久久久牛牛 | 亚洲视频播放 | 九九小视频| 国产精品自拍片 | 日本性欧美 | 91老师国产黑色丝袜在线 | 天堂少妇 | 又黄又爽的视频在线观看 | 91精品国产91综合久久蜜臀 | 无码精品国产一区二区三区免费 | 中文字幕亚洲一区二区三区五十路 | 亚洲国产中文字幕在线观看 | com国产 | 依依激情网 | 亚洲欧美日韩一区在线观看 | 在线观看成人一区 | 美国黄色av | 日本在线一区二区 | 国产日韩欧美一区二区 | 极品探花在线观看 | 人人妻人人澡人人爽人人dvd | 成人福利网站在线观看 |