日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

spring獲取bean的源碼解析

瀏覽:103日期:2023-07-16 16:29:10
介紹

前面一章說了AbstractApplicationContext中的refresh方法中的invokeBeanFactoryPostProcessors。主要是調用BeanFactoryPostProcessor。其中也有獲取bean的過程,就是beanFactory.getBean的方法。這一章就說下getBean這個方法。由于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的整個流程

1.先轉換bean的名稱,轉換成beanName。這里意思就是,我們在獲取bean的時候,可能是FactoryBean的名稱(&開頭),這里轉成不帶&開頭的名稱,如果有別名,再獲取別名。

2.從緩存中獲取bean,這里的緩存分為一二三級緩存,也就是我們常常被問到了spring三級緩存,具體邏輯下面再說。

3.根據獲取的到對象再去獲取我們想要的bean,因為這里獲取到的對象可能是我們需要的bean,也可能是FactoryBean。

4.如果緩存中沒有,那么我們就要自己去創建bean了。

5.查看有沒有父類的BeanFactory,如果有,那么就父類去創建bean。

6.獲取要創建的bean對象的@DependsOn注解上的名稱,先去創建DependsOn的bean,并且校驗是否存在循環引用

7.創建bean,根據類型創建不同的bean,比如singleton,prototype,request,session等。

8.如果需要轉換類型,則進行類型轉換。

整體的獲取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通過三級緩存來解決循環依賴的問題。簡單來介紹下三級緩存。

1. singletonObjects為一級緩存,我們實例化的bean都在這個map里,俠義的說singletonObjects才是我們真正的spring容器,存放bean的地方。

2. earlySingletonObjects為二級緩存,是存放未完成的bean的緩存,如果有代理的話,存放的是代理對象。

3. 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,這里也簡單說下流程

1. 首先判斷name是不是FactoryBean的name,也就是&開頭的name,如果是去判斷beanInstance是不是FactoryBean,如果beanInstance不是FactoryBean則拋異常。

2. 由于上面已經判斷過,如果name是FactoryBeanName,但是BeanInstance不是FactoryBean的話,就會拋出異常。所以如果BeanInstance如果不是FactoryBean的話,那么name一定不是FactoryBeanName。那么就直接返回BeanInstance就是我們需要的了。

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

3. 如果都沒有返回,那么已經可以確定我們此時的已經可以確定BeanInstance是FactoryBean了,因為如果不是FactoryBean的話,在!(beanInstance instanceof FactoryBean)就已經返回了。

4. 通過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這里還是有點復雜的。這里再進行一個簡單梳理。

1. 根據class還有bean以及參數創建bean。

2. 調用beanPostprocessor的方法,調用屬于MergedBeanDefinitionPostProcessor的方法。對bean進行一些處理,比如找到那些依賴的bean的field和method。

3. 將bean加入到三級緩存中去。

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

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

6. 接著進行校驗。這里稍微比較復雜一點。如果從二級緩存能取到,那就說明之前被別人從三級緩存拿出來過了。可能是因為循環依賴,也可能是因為別的地方調用了getBean方法了。從三級緩存拿出來的時候有個getEarlyBeanReference的方法,就是查看是否要生成代理的bean。如果生成過了,那么在調用第五步的時候,就不會在生成代理了。這樣exposedObject ==bean,直接只用代理返回。

如果不相等:這里的情況就是如果是spring自己的@Async,在從二級緩存生成代理之后,再去調用第五步時候一樣會生成代理。所以exposedObject !=bean,所以在再往下發現有循環調用,并且bean還在創建時,就會拋出異常了。所以一般慎用spring的@Async。但是一般也可以使用@Lazy進行處理。至于原理后面再說。

到這里spring的創建bean就結束了。然后返回時候就到了入口方法getBean的getObjectForBeanInstance的方法,到底需要的bean還是FactoryBean。

最后就是如果requiredType和實例不一樣就要進行類型轉換了。

總結

本篇大概說下spring獲取bean和加到容器里面的流程。其實廣義上來說Bean的容器是BeanFactory或者applicationContext。狹義上說就是一個map。也就是一級緩存SingletonObjects。我們獲取的真正需要的bean也就是從中獲取的。本篇只是簡要的說了下bean獲取和加入容器的整個流程,具體的根據無參構造器創建bean,有參數構造器創建bean。還有對于創建bean中依賴的bean的查找還有創建,三級緩存如何解決循環依賴還有為何不能解決構造器依賴,以及bean調用初始化的等等操作都沒有說。因為一篇說起來確實太長了。后面都會一一去分析。

到此這篇關于spring獲取bean的源碼解析的文章就介紹到這了,更多相關spring獲取bean源碼內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
一级成人国产| 欧美亚洲一区二区三区| 国产精品久久久久蜜臀 | 亚洲国产不卡| 欧美日韩精品在线一区| 欧美69视频| 亚洲激情二区| 九一成人免费视频| 99xxxx成人网| 欧美专区一区二区三区| 亚洲色图综合| 日韩高清中文字幕一区| 国产精品3区| 国产在线一区不卡| 日本久久成人网| 在线亚洲免费| 日韩激情精品| 福利精品一区| 欧美在线影院| 日韩和欧美一区二区| 免费在线日韩av| 欧美国产美女| 中文亚洲免费| 亚洲ww精品| 美女在线视频一区| 国产精品久久久一区二区| 亚洲深深色噜噜狠狠爱网站| 国产欧美日韩在线一区二区| 国产成人精品一区二区免费看京| 日韩精品诱惑一区?区三区| 国产乱子精品一区二区在线观看| 国产成人久久精品麻豆二区| 影视先锋久久| 亚洲久草在线| 精品一区二区三区免费看| 欧美激情国产在线| 在线一区免费| 国产麻豆一区| 麻豆国产欧美一区二区三区| 亚洲国内欧美| 欧美一区激情| 亚洲精品.com| 亚洲精品在线国产| 91一区二区三区四区| 亚洲国产一区二区三区在线播放| 日本不卡视频一二三区| 成人在线视频中文字幕| 亚洲一区不卡| 久久精品毛片| 在线视频日韩| 麻豆一区二区在线| 欧美日韩国产欧| 国产精品久久久久av蜜臀| 久久久精品久久久久久96| 日韩精品成人| 亚洲91久久| 日本一区免费网站| 国产99久久| 国产探花在线精品| 99热精品在线| 精品国产美女a久久9999| 蜜臀av性久久久久蜜臀aⅴ四虎| 天堂va欧美ⅴa亚洲va一国产| se01亚洲视频| 日韩一区二区三免费高清在线观看 | 亚洲播播91| 日韩精品一级中文字幕精品视频免费观看 | 麻豆久久一区| 蜜桃av一区二区| 中文在线免费视频| 日韩高清不卡在线| 国产高清久久| 国产一区二区三区黄网站| 婷婷综合电影| 久久久久午夜电影| 久久久久亚洲精品中文字幕| 国产亚洲一级| 在线看片福利| 国产精品一卡| 亚洲精品日本| 亚洲一区日本| 99精品视频在线| 免费人成精品欧美精品| 激情六月综合| 日韩av专区| 国产精品一站二站| 伊人精品久久| 99香蕉国产精品偷在线观看| 亚洲一区资源| 欧美日韩日本国产亚洲在线| 日韩精品2区| 国产精品美女在线观看直播| 久久大逼视频| 午夜久久一区| 99热精品久久| 日韩中文欧美| 91欧美国产| 精品视频91| 国产激情久久| 国产色噜噜噜91在线精品| 日韩中出av| 免费高清在线一区| 日韩一级精品| 亚洲一级网站| 久久天堂精品| 神马日本精品| 国产成人77亚洲精品www| 国产精久久一区二区| 国产日韩在线观看视频| 日本亚洲视频在线| 亚洲久久视频| 亚洲精品美女91| 亚洲网址在线观看| 视频一区国产视频| 乱人伦精品视频在线观看| 日韩1区2区日韩1区2区| 青青国产91久久久久久| 91成人在线| 欧美日韩在线精品一区二区三区激情综合 | 久久久精品久久久久久96| 天堂√8在线中文| 日韩av二区| 免费在线小视频| 丝袜美腿诱惑一区二区三区| 日韩在线精品| 青青久久av| 91久久久精品国产| 亚洲免费中文| 免费的成人av| 日产欧产美韩系列久久99| 日韩激情综合| 国产精品分类| 精品一区二区三区亚洲| 欧美男人天堂| 尤物tv在线精品| 先锋影音国产一区| 日韩专区在线视频| 日韩激情网站| 久久精品一本| 天堂8中文在线最新版在线| 伊人精品一区| 久热re这里精品视频在线6| 亚洲精选久久| 国产精品久一| av高清不卡| 午夜国产一区二区| а√在线中文在线新版| 欧美手机在线| 亚洲色图网站| 老司机免费视频一区二区| 天堂а√在线最新版中文在线| 久久视频精品| 亚洲人成网77777色在线播放 | 播放一区二区| 国产日韩专区| 97精品久久| 日韩88av| 亚洲国内精品| 亚洲a成人v| 精品福利久久久| 亚洲精品a级片| 国产乱人伦精品一区| 麻豆精品蜜桃| 亚洲另类av| 久久这里只有精品一区二区| 久久裸体视频| 日本一区二区三区视频在线看| 国产不卡精品| 免费在线观看一区二区三区| 久久在线91| 亚洲深夜av| 精品五月天堂| 免费欧美一区| 国产欧美一级| 久久视频精品| 久久精品凹凸全集| 久久婷婷丁香| 日韩国产在线观看一区| 群体交乱之放荡娇妻一区二区| 亚洲欧洲免费| 亚洲精品日韩久久| 五月激情久久| 日本不卡视频在线| 日韩一区自拍| 日韩国产一区二| 免费视频亚洲| 精品精品久久| 亚洲激情五月| 久久精品国产福利| 免费看黄色91| 国产午夜一区| 麻豆亚洲精品| 日韩免费高清| 亚洲欧美专区| 91精品国产乱码久久久久久久 | 免费亚洲一区| 一区二区三区四区日韩| www.九色在线| 日韩精品一区二区三区免费视频| 免费污视频在线一区|