精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

驚呆了,Spring中竟然有12種定義Bean的方法

開發 架構
在龐大的java體系中,spring有著舉足輕重的地位,它給每位開發者帶來了極大的便利和驚喜。我們都知道spring是創建和管理bean的工廠,它提供了多種定義bean的方式,能夠滿足我們日常工作中的多種業務場景。

[[409379]]

本文轉載自微信公眾號「蘇三說技術」,作者因為熱愛所以堅持ing 。轉載本文請聯系蘇三說技術公眾號。

前言

在龐大的java體系中,spring有著舉足輕重的地位,它給每位開發者帶來了極大的便利和驚喜。我們都知道spring是創建和管理bean的工廠,它提供了多種定義bean的方式,能夠滿足我們日常工作中的多種業務場景。

那么問題來了,你知道spring中有哪些方式可以定義bean?

我估計很多人會說出以下三種:

沒錯,但我想說的是以上三種方式只是開胃小菜,實際上spring的功能遠比你想象中更強大。

各位看官如果不信,請繼續往下看。

1. xml文件配置bean

我們先從xml配置bean開始,它是spring最早支持的方式。后來,隨著springboot越來越受歡迎,該方法目前已經用得很少了,但我建議我們還是有必要了解一下。

1.1 構造器

如果你之前有在bean.xml文件中配置過bean的經歷,那么對如下的配置肯定不會陌生:

  1. <bean id="personService" class="com.sue.cache.service.test7.PersonService"
  2. </bean> 

這種方式是以前使用最多的方式,它默認使用了無參構造器創建bean。

當然我們還可以使用有參的構造器,通過標簽來完成配置。

  1. <bean id="personService" class="com.sue.cache.service.test7.PersonService"
  2.    <constructor-arg index="0" value="susan"></constructor-arg> 
  3.    <constructor-arg index="1" ref="baseInfo"></constructor-arg> 
  4. </bean> 

其中:

  • index表示下標,從0開始。
  • value表示常量值
  • ref表示引用另一個bean

1.2 setter方法

除此之外,spring還提供了另外一種思路:通過setter方法設置bean所需參數,這種方式耦合性相對較低,比有參構造器使用更為廣泛。

先定義Person實體:

  1. @Data 
  2. public class Person { 
  3.     private String name
  4.     private int age; 

它里面包含:成員變量name和age,getter/setter方法。

然后在bean.xml文件中配置bean時,加上<:property>標簽設置bean所需參數。

  1. <bean id="person" class="com.sue.cache.service.test7.Person"
  2.    <property name="name" value="susan"></constructor-arg> 
  3.    <property name="age" value="18"></constructor-arg> 
  4. </bean> 

1.3 靜態工廠

這種方式的關鍵是需要定義一個工廠類,它里面包含一個創建bean的靜態方法。例如:

  1. public class SusanBeanFactory { 
  2.     public static Person createPerson(String nameint age) { 
  3.         return new Person(name, age); 
  4.     } 

接下來定義Person類如下:

  1. @AllArgsConstructor 
  2. @NoArgsConstructor 
  3. @Data 
  4. public class Person { 
  5.     private String name
  6.     private int age; 

它里面包含:成員變量name和age,getter/setter方法,無參構造器和全參構造器。

然后在bean.xml文件中配置bean時,通過factory-method參數指定靜態工廠方法,同時通過設置相關參數。

  1. <bean class="com.sue.cache.service.test7.SusanBeanFactory" factory-method="createPerson"
  2.    <constructor-arg index="0" value="susan"></constructor-arg> 
  3.    <constructor-arg index="1" value="18"></constructor-arg> 
  4. </bean> 

1.4 實例工廠方法

這種方式也需要定義一個工廠類,但里面包含非靜態的創建bean的方法。

  1. public class SusanBeanFactory { 
  2.     public Person createPerson(String nameint age) { 
  3.         return new Person(name, age); 
  4.     } 

Person類跟上面一樣,就不多說了。

然后bean.xml文件中配置bean時,需要先配置工廠bean。然后在配置實例bean時,通過factory-bean參數指定該工廠bean的引用。

  1. <bean id="susanBeanFactory" class="com.sue.cache.service.test7.SusanBeanFactory"
  2. </bean> 
  3. <bean factory-bean="susanBeanFactory" factory-method="createPerson"
  4.    <constructor-arg index="0" value="susan"></constructor-arg> 
  5.    <constructor-arg index="1" value="18"></constructor-arg> 
  6. </bean> 

1.5 FactoryBean

不知道大家有沒有發現,上面的實例工廠方法每次都需要創建一個工廠類,不方面統一管理。

這時我們可以使用FactoryBean接口。

  1. public class UserFactoryBean implements FactoryBean<User> { 
  2.     @Override 
  3.     public User getObject() throws Exception { 
  4.         return new User(); 
  5.     } 
  6.  
  7.     @Override 
  8.     public Class<?> getObjectType() { 
  9.         return User.class; 
  10.     } 

在它的getObject方法中可以實現我們自己的邏輯創建對象,并且在getObjectType方法中我們可以定義對象的類型。

然后在bean.xml文件中配置bean時,只需像普通的bean一樣配置即可。

  1. <bean id="userFactoryBean" class="com.sue.async.service.UserFactoryBean"
  2. </bean> 

輕松搞定,so easy。

注意:getBean("userFactoryBean");獲取的是getObject方法中返回的對象。而getBean("&userFactoryBean");獲取的才是真正的UserFactoryBean對象。

我們通過上面五種方式,在bean.xml文件中把bean配置好之后,spring就會自動掃描和解析相應的標簽,并且幫我們創建和實例化bean,然后放入spring容器中。

雖說基于xml文件的方式配置bean,簡單而且非常靈活,比較適合一些小項目。但如果遇到比較復雜的項目,則需要配置大量的bean,而且bean之間的關系錯綜復雜,這樣久而久之會導致xml文件迅速膨脹,非常不利于bean的管理。

2. Component注解

為了解決bean太多時,xml文件過大,從而導致膨脹不好維護的問題。在spring2.5中開始支持:@Component、@Repository、@Service、@Controller等注解定義bean。

如果你有看過這些注解的源碼的話,就會驚奇得發現:其實后三種注解也是@Component。

@Component系列注解的出現,給我們帶來了極大的便利。我們不需要像以前那樣在bean.xml文件中配置bean了,現在只用在類上加Component、Repository、Service、Controller,這四種注解中的任意一種,就能輕松完成bean的定義。

  1. @Service 
  2. public class PersonService { 
  3.     public String get() { 
  4.         return "data"
  5.     } 

其實,這四種注解在功能上沒有特別的區別,不過在業界有個不成文的約定:

  • Controller 一般用在控制層
  • Service 一般用在業務層
  • Repository 一般用在數據層
  • Component 一般用在公共組件上

太棒了,簡直一下子解放了我們的雙手。

不過,需要特別注意的是,通過這種@Component掃描注解的方式定義bean的前提是:需要先配置掃描路徑。

目前常用的配置掃描路徑的方式如下:

在applicationContext.xml文件中使用標簽。例如:

  1. <context:component-scan base-package="com.sue.cache" /> 

在springboot的啟動類上加上@ComponentScan注解,例如:

  1. @ComponentScan(basePackages = "com.sue.cache"
  2. @SpringBootApplication 
  3. public class Application { 
  4.  
  5.     public static void main(String[] args) { 
  6.         new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args); 
  7.     } 

直接在SpringBootApplication注解上加,它支持ComponentScan功能:

  1. @SpringBootApplication(scanBasePackages = "com.sue.cache"
  2. public class Application { 
  3.      
  4.     public static void main(String[] args) { 
  5.         new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args); 
  6.     } 

當然,如果你需要掃描的類跟springboot的入口類,在同一級或者子級的包下面,無需指定scanBasePackages參數,spring默認會從入口類的同一級或者子級的包去找。

  1. @SpringBootApplication 
  2. public class Application { 
  3.      
  4.     public static void main(String[] args) { 
  5.         new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args); 
  6.     } 

此外,除了上述四種@Component注解之外,springboot還增加了@RestController注解,它是一種特殊的@Controller注解,所以也是@Component注解。

@RestController還支持@ResponseBody注解的功能,即將接口響應數據的格式自動轉換成json。

@Component系列注解已經讓我們愛不釋手了,它目前是我們日常工作中最多的定義bean的方式。

3. JavaConfig

@Component系列注解雖說使用起來非常方便,但是bean的創建過程完全交給spring容器來完成,我們沒辦法自己控制。

spring從3.0以后,開始支持JavaConfig的方式定義bean。它可以看做spring的配置文件,但并非真正的配置文件,我們需要通過編碼java代碼的方式創建bean。例如:

  1. public class MyConfiguration { 
  2.  
  3.     @Bean 
  4.     public Person person() { 
  5.         return new Person(); 
  6.     } 

在JavaConfig類上加@Configuration注解,相當于配置了標簽。而在方法上加@Bean注解,相當于配置了標簽。

此外,springboot還引入了一些列的@Conditional注解,用來控制bean的創建。

  1. @Configuration 
  2. public class MyConfiguration { 
  3.  
  4.     @ConditionalOnClass(Country.class) 
  5.     @Bean 
  6.     public Person person() { 
  7.         return new Person(); 
  8.     } 

@ConditionalOnClass注解的功能是當項目中存在Country類時,才實例化Person類。換句話說就是,如果項目中不存在Country類,就不實例化Person類。

這個功能非常有用,相當于一個開關控制著Person類,只有滿足一定條件才能實例化。

spring中使用比較多的Conditional還有:

  • ConditionalOnBean
  • ConditionalOnProperty
  • ConditionalOnMissingClass
  • ConditionalOnMissingBean
  • ConditionalOnWebApplication

如果你對這些功能比較感興趣,可以看看《spring中那些讓你愛不釋手的代碼技巧(續集)》,這是我之前寫的一篇文章,里面做了更詳細的介紹。

下面用一張圖整體認識一下@Conditional家族:

nice,有了這些功能,我們終于可以告別麻煩的xml時代了。

4. Import注解

通過前面介紹的@Configuration和@Bean相結合的方式,我們可以通過代碼定義bean。但這種方式有一定的局限性,它只能創建該類中定義的bean實例,不能創建其他類的bean實例,如果我們想創建其他類的bean實例該怎么辦呢?

這時可以使用@Import注解導入。

4.1 普通類

spring4.2之后@Import注解可以實例化普通類的bean實例。例如:

先定義了Role類:

  1. @Data 
  2. public class Role { 
  3.     private Long id; 
  4.     private String name

接下來使用@Import注解導入Role類:

  1. @Import(Role.class) 
  2. @Configuration 
  3. public class MyConfig { 

然后在調用的地方通過@Autowired注解注入所需的bean。

  1. @RequestMapping("/"
  2. @RestController 
  3. public class TestController { 
  4.  
  5.     @Autowired 
  6.     private Role role; 
  7.  
  8.     @GetMapping("/test"
  9.     public String test() { 
  10.         System.out.println(role); 
  11.         return "test"
  12.     } 

聰明的你可能會發現,我沒有在任何地方定義過Role的bean,但spring卻能自動創建該類的bean實例,這是為什么呢?

這也許正是@Import注解的強大之處。

此時,有些朋友可能會問:@Import注解能定義單個類的bean,但如果有多個類需要定義bean該怎么辦呢?

恭喜你,這是個好問題,因為@Import注解也支持。

  1. @Import({Role.class, User.class}) 
  2. @Configuration 
  3. public class MyConfig { 

甚至,如果你想偷懶,不想寫這種MyConfig類,springboot也歡迎。

  1. @Import({Role.class, User.class}) 
  2. @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, 
  3.         DataSourceTransactionManagerAutoConfiguration.class}) 
  4. public class Application { 
  5.  
  6.     public static void main(String[] args) { 
  7.         new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args); 
  8.     } 

可以將@Import加到springboot的啟動類上。

這樣也能生效?

springboot的啟動類一般都會加@SpringBootApplication注解,該注解上加了@SpringBootConfiguration注解。

而@SpringBootConfiguration注解,上面又加了@Configuration注解。

所以,springboot啟動類本身帶有@Configuration注解的功能。

意不意外?驚不驚喜?

4.2 Configuration類

上面介紹了@Import注解導入普通類的方法,它同時也支持導入Configuration類。

先定義一個Configuration類:

  1. @Configuration 
  2. public class MyConfig2 { 
  3.  
  4.     @Bean 
  5.     public User user() { 
  6.         return  new User(); 
  7.     } 
  8.  
  9.     @Bean 
  10.     public Role role() { 
  11.         return new Role(); 
  12.     } 

然后在另外一個Configuration類中引入前面的Configuration類:

  1. @Import({MyConfig2.class}) 
  2. @Configuration 
  3. public class MyConfig { 

這種方式,如果MyConfig2類已經在spring指定的掃描目錄或者子目錄下,則MyConfig類會顯得有點多余。因為MyConfig2類本身就是一個配置類,它里面就能定義bean。

但如果MyConfig2類不在指定的spring掃描目錄或者子目錄下,則通過MyConfig類的導入功能,也能把MyConfig2類識別成配置類。這就有點厲害了喔。

其實下面還有更高端的玩法。

swagger作為一個優秀的文檔生成框架,在spring項目中越來越受歡迎。接下來,我們以swagger2為例,介紹一下它是如何導入相關類的。

眾所周知,我們引入swagger相關jar包之后,只需要在springboot的啟動類上加上@EnableSwagger2注解,就能開啟swagger的功能。

其中@EnableSwagger2注解中導入了Swagger2DocumentationConfiguration類。

該類是一個Configuration類,它又導入了另外兩個類:

  • SpringfoxWebMvcConfiguration
  • SwaggerCommonConfiguration

SpringfoxWebMvcConfiguration類又會導入新的Configuration類,并且通過@ComponentScan注解掃描了一些其他的路徑。

SwaggerCommonConfiguration同樣也通過@ComponentScan注解掃描了一些額外的路徑。

如此一來,我們通過一個簡單的@EnableSwagger2注解,就能輕松的導入swagger所需的一系列bean,并且擁有swagger的功能。

還有什么好說的,狂起點贊,簡直完美。

4.3 ImportSelector

上面提到的Configuration類,它的功能非常強大。但怎么說呢,它不太適合加復雜的判斷條件,根據某些條件定義這些bean,根據另外的條件定義那些bean。

那么,這種需求該怎么實現呢?

這時就可以使用ImportSelector接口了。

首先定義一個類實現ImportSelector接口:

  1. public class DataImportSelector implements ImportSelector { 
  2.     @Override 
  3.     public String[] selectImports(AnnotationMetadata importingClassMetadata) { 
  4.         return new String[]{"com.sue.async.service.User""com.sue.async.service.Role"}; 
  5.     } 

重寫selectImports方法,在該方法中指定需要定義bean的類名,注意要包含完整路徑,而非相對路徑。

然后在MyConfig類上@Import導入這個類即可:

  1. @Import({DataImportSelector.class}) 
  2. @Configuration 
  3. public class MyConfig { 

朋友們是不是又發現了一個新大陸?

不過,這個注解還有更牛逼的用途。

@EnableAutoConfiguration注解中導入了AutoConfigurationImportSelector類,并且里面包含系統參數名稱:spring.boot.enableautoconfiguration。

AutoConfigurationImportSelector類實現了ImportSelector接口。

并且重寫了selectImports方法,該方法會根據某些注解去找所有需要創建bean的類名,然后返回這些類名。其中在查找這些類名之前,先調用isEnabled方法,判斷是否需要繼續查找。

該方法會根據ENABLED_OVERRIDE_PROPERTY的值來作為判斷條件。

而這個值就是spring.boot.enableautoconfiguration。

換句話說,這里能根據系統參數控制bean是否需要被實例化,優秀。

我個人認為實現ImportSelector接口的好處主要有以下兩點:

  • 把某個功能的相關類,可以放到一起,方面管理和維護。
  • 重寫selectImports方法時,能夠根據條件判斷某些類是否需要被實例化,或者某個條件實例化這些bean,其他的條件實例化那些bean等。我們能夠非常靈活的定制化bean的實例化。

4.4 ImportBeanDefinitionRegistrar

我們通過上面的這種方式,確實能夠非常靈活的自定義bean。

但它的自定義能力,還是有限的,它沒法自定義bean的名稱和作用域等屬性。

有需求,就有解決方案。

接下來,我們一起看看ImportBeanDefinitionRegistrar接口的神奇之處。

先定義CustomImportSelector類實現ImportBeanDefinitionRegistrar接口:

  1. public class CustomImportSelector implements ImportBeanDefinitionRegistrar { 
  2.  
  3.     @Override 
  4.     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 
  5.         RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class); 
  6.         registry.registerBeanDefinition("role", roleBeanDefinition); 
  7.  
  8.         RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class); 
  9.         userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); 
  10.         registry.registerBeanDefinition("user", userBeanDefinition); 
  11.     } 

重寫registerBeanDefinitions方法,在該方法中我們可以獲取BeanDefinitionRegistry對象,通過它去注冊bean。不過在注冊bean之前,我們先要創建BeanDefinition對象,它里面可以自定義bean的名稱、作用域等很多參數。

然后在MyConfig類上導入上面的類:

  1. @Import({CustomImportSelector.class}) 
  2. @Configuration 
  3. public class MyConfig { 

我們所熟悉的fegin功能,就是使用ImportBeanDefinitionRegistrar接口實現的:

具體細節就不多說了,有興趣的朋友可以加我微信找我私聊。

5. PostProcessor

除此之外,spring還提供了專門注冊bean的接口:BeanDefinitionRegistryPostProcessor。

該接口的方法postProcessBeanDefinitionRegistry上有這樣一段描述:

修改應用程序上下文的內部bean定義注冊表標準初始化。所有常規bean定義都將被加載,但是還沒有bean被實例化。這允許進一步添加在下一個后處理階段開始之前定義bean。

如果用這個接口來定義bean,我們要做的事情就變得非常簡單了。只需定義一個類實現BeanDefinitionRegistryPostProcessor接口。

  1. @Component 
  2. public class MyRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { 
  3.     @Override 
  4.     public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 
  5.         RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class); 
  6.         registry.registerBeanDefinition("role", roleBeanDefinition); 
  7.  
  8.         RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class); 
  9.         userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); 
  10.         registry.registerBeanDefinition("user", userBeanDefinition); 
  11.     } 
  12.  
  13.     @Override 
  14.     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
  15.     } 

重寫postProcessBeanDefinitionRegistry方法,在該方法中能夠獲取BeanDefinitionRegistry對象,它負責bean的注冊工作。

不過細心的朋友可能會發現,里面還多了一個postProcessBeanFactory方法,沒有做任何實現。

這個方法其實是它的父接口:BeanFactoryPostProcessor里的方法。

在應用程序上下文的標準bean工廠之后修改其內部bean工廠初始化。所有bean定義都已加載,但沒有bean將被實例化。這允許重寫或添加屬性甚至可以初始化bean。

  1. @Component 
  2. public class MyPostProcessor implements BeanFactoryPostProcessor { 
  3.  
  4.     @Override 
  5.     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
  6.         DefaultListableBeanFactory registry = (DefaultListableBeanFactory)beanFactory; 
  7.         RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class); 
  8.         registry.registerBeanDefinition("role", roleBeanDefinition); 
  9.  
  10.         RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class); 
  11.         userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); 
  12.         registry.registerBeanDefinition("user", userBeanDefinition); 
  13.     } 

既然這兩個接口都能注冊bean,那么他們有什么區別?

  • BeanDefinitionRegistryPostProcessor 更側重于bean的注冊
  • BeanFactoryPostProcessor 更側重于對已經注冊的bean的屬性進行修改,雖然也可以注冊bean。

此時,有些朋友可能會問:既然拿到BeanDefinitionRegistry對象就能注冊bean,那通過BeanFactoryAware的方式是不是也能注冊bean呢?

從下面這張圖能夠看出DefaultListableBeanFactory就實現了BeanDefinitionRegistry接口。

這樣一來,我們如果能夠獲取DefaultListableBeanFactory對象的實例,然后調用它的注冊方法,不就可以注冊bean了?

說時遲那時快,定義一個類實現BeanFactoryAware接口:

  1. @Component 
  2. public class BeanFactoryRegistry implements BeanFactoryAware { 
  3.     @Override 
  4.     public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
  5.         DefaultListableBeanFactory registry = (DefaultListableBeanFactory) beanFactory; 
  6.         RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class); 
  7.         registry.registerBeanDefinition("user", rootBeanDefinition); 
  8.  
  9.         RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class); 
  10.         userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE); 
  11.         registry.registerBeanDefinition("user", userBeanDefinition); 
  12.     } 

重寫setBeanFactory方法,在該方法中能夠獲取BeanFactory對象,它能夠強制轉換成DefaultListableBeanFactory對象,然后通過該對象的實例注冊bean。

當你滿懷喜悅的運行項目時,發現竟然報錯了:

為什么會報錯?

spring中bean的創建過程順序,大致如下:

BeanFactoryAware接口是在bean創建成功,并且完成依賴注入之后,在真正初始化之前才被調用的。在這個時候去注冊bean意義不大,因為這個接口是給我們獲取bean的,并不建議去注冊bean,會引發很多問題。

此外,ApplicationContextRegistry和ApplicationListener接口也有類似的問題,我們可以用他們獲取bean,但不建議用它們注冊bean。

 

責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2022-02-14 12:04:43

前綴SpringJpa

2020-07-07 07:37:36

Integer源碼Java

2025-11-04 02:00:00

2019-09-18 15:20:16

MyBatisSQL數據庫

2020-11-03 06:57:10

MyBatis數據庫

2020-04-02 07:31:53

RPC超時服務端

2024-07-05 11:47:43

2020-11-27 09:16:21

BlockingQue

2022-09-04 12:43:03

算法裁員Meta

2020-01-06 09:14:59

Java程序員線程

2009-06-17 17:04:37

BeanFactorySpring

2019-06-14 08:48:46

Tomcat日志SpringBoot

2021-03-17 11:47:37

tomcatJavaServerJava

2015-05-19 14:30:48

加密視頻加密億賽通

2015-07-20 15:26:56

WiFi感知

2023-07-27 08:14:29

2021-11-02 11:31:47

Go代碼模式

2021-12-13 22:52:37

iphone iOSHTML

2021-05-28 10:09:22

GC詳解Java JVM

2022-06-24 14:52:34

AI模型
點贊
收藏

51CTO技術棧公眾號

91捆绑美女网站| 激情偷拍久久| 日韩欧美视频在线| 国产综合av在线| 国产三级视频在线看| 久久成人免费网| 午夜精品在线观看| 一区二区三区久久久久| 一区在线不卡| 精品福利一区二区| 一区二区免费在线视频| 亚洲欧美黄色片| 老司机午夜精品视频| 久久躁狠狠躁夜夜爽| 久久丫精品国产亚洲av不卡| 黄页免费欧美| 性做久久久久久| 中文精品视频一区二区在线观看| 俄罗斯嫩小性bbwbbw| 丝袜国产日韩另类美女| 欧美贵妇videos办公室| 欧美老女人性生活视频| 久久porn| 欧美一区二区三级| 国产精品乱码久久久久| av电影免费在线看| 中文字幕综合网| 蜜桃传媒视频麻豆一区 | 免费电影视频在线看| 国产欧美1区2区3区| 激情伦成人综合小说| 国产伦理一区二区| 蜜臀av性久久久久蜜臀av麻豆| 午夜精品福利在线观看| 人人澡人人澡人人看| 精品色999| 亚洲美女av电影| www国产视频| 精品一区二区三区中文字幕视频| 欧美视频一二三区| 国产男女激情视频| 日本不卡网站| 午夜精品一区二区三区三上悠亚| 国产成人生活片| 黄色在线免费看| 国产精品福利一区| 亚洲一区二区三区免费观看| 九色在线播放| 国产亚洲精品超碰| 欧美日韩高清免费| 你懂的在线网址| 9i在线看片成人免费| 国产精品免费观看高清| 亚洲精品免费在线观看视频| 国产成人自拍高清视频在线免费播放| 成人免费视频网址| 亚洲中文字幕一区二区| 麻豆成人av在线| 成人疯狂猛交xxx| 国产又黄又爽视频| 国产一区二区精品在线观看| 91久久国产精品91久久性色| 国产精品久久久久久无人区| 免费人成精品欧美精品| 国产欧美日韩视频| 国产理论片在线观看| 国产综合色精品一区二区三区| 成人免费高清完整版在线观看| 国产女无套免费视频| 国产精品白丝av| 99国产在线视频| 黄色av一区二区三区| 99久久777色| 人禽交欧美网站免费| 91社区在线观看| 亚洲欧美日韩国产成人精品影院 | 波多野结衣一本| 精品日产免费二区日产免费二区| 中文字幕亚洲欧美日韩2019| 日韩av手机在线免费观看| 亚洲精彩视频| 91精品国产91久久久久久最新| 9i看片成人免费看片| 老汉av免费一区二区三区| 91传媒在线免费观看| 少妇精品高潮欲妇又嫩中文字幕 | 国产精品一区二区三区99| 国产精品 日韩| 国产在线一在线二| 成人免费在线观看入口| 成人免费视频91| 亚洲第一会所001| 91精品国产入口在线| 欧美肉大捧一进一出免费视频| 国产真实有声精品录音| 欧美精品生活片| 国产一级一级国产| 国产精品小仙女| 日韩在线第一区| 久草在线视频资源| 欧美体内she精视频| 久久久久无码国产精品一区李宗瑞 | 在线视频亚洲欧美中文| 亚洲精品日韩丝袜精品| 国产性生活大片| 亚洲一区欧美二区| 亚洲在线免费观看| 国产一级片在线播放| 一区二区在线观看视频 | 强乱中文字幕av一区乱码| 另类av一区二区| 成人3d动漫一区二区三区91| а天堂8中文最新版在线官网| 亚洲一二三四在线观看| 亚洲国产高清av| 日本天堂一区| 欧美夫妻性生活视频| 在线观看黄色网| 91视频一区二区三区| 伊人久久在线观看| 开心久久婷婷综合中文字幕| 亚洲国产精品悠悠久久琪琪| 欧美人禽zoz0强交| 美日韩一区二区三区| 免费不卡亚洲欧美| 97超碰免费在线| 日韩一区二区在线看| 中文字幕精品亚洲| 久久亚洲国产精品一区二区| 国产成人精品日本亚洲11| 成人福利网站| 欧美精品在线一区二区| 五月激情四射婷婷| 天堂精品中文字幕在线| 精品欧美国产| 蜜桃麻豆影像在线观看| 亚洲第一页在线| 久久久久无码国产精品| 国产成人一区在线| 狠狠干视频网站| 国产一区二区久久久久| 日韩视频免费中文字幕| 中文在线字幕免费观| 国产午夜三级一区二区三| 黄色片一级视频| 自拍偷拍一区| 国产精品91在线| 成人在线免费视频| 欧美日韩国产一级片| 影音先锋男人看片资源| 久久国产麻豆精品| 一区二区三区四区| av日韩在线免费观看| 久久精品亚洲热| 99热这里只有精品1| 一区二区视频免费在线观看| 免费不卡av网站| 国精品一区二区三区| 国产精品久久一区二区三区| 久久五月精品中文字幕| 亚洲激情视频网站| 亚洲毛片一区二区三区| 国产日韩av一区| www.se五月| 欧美激情91| 国产精选在线观看91| 捆绑调教日本一区二区三区| 亚洲精品一区久久久久久| 国产女主播喷水视频在线观看| 国产日产欧美精品一区二区三区| 国产天堂在线播放| 天天综合网网欲色| 官网99热精品| xx欧美xxx| 日韩在线观看免费| 成人午夜福利视频| 色偷偷88欧美精品久久久| 超碰人人人人人人人| 国产精品99久久久久| 香港三级韩国三级日本三级| 日韩精品一区二区三区免费观影 | 国产一区二区在线观看免费视频| 亚洲欧美综合久久久| 国产乱码精品一区二区三区中文 | 亚洲高清不卡av| 无码人妻精品一区二区三区蜜桃91| 国产蜜臀av在线一区二区三区| 肉色超薄丝袜脚交| 国产亚洲精品bv在线观看| 神马欧美一区二区| 2023国产精华国产精品| 国产精品电影一区| 怡红院在线播放| 亚洲欧美在线一区| 精品人妻伦一二三区久久| 色综合色综合色综合| 三级影片在线看| 久久久久久电影| 久久久久亚洲av无码麻豆| 久久成人免费| www.欧美黄色| 青青草成人影院| 九九热久久66| 欧美黄色一级| 国产精品免费小视频| 超碰在线视屏| 欧美成人午夜视频| a天堂中文在线88| 亚洲国产天堂久久综合网| 国产精品久久久久久久一区二区 | 亚洲av永久无码国产精品久久| 在线亚洲一区二区| 亚洲激情视频一区| 亚洲天堂精品视频| 人妻少妇无码精品视频区| 成人国产视频在线观看| www.色就是色.com| 天堂成人国产精品一区| 福利视频一区二区三区四区| 国产精品国产一区| 丝袜足脚交91精品| 亚洲丁香日韩| 精品国产一区二区三| 美女久久精品| 成人欧美在线视频| 日韩有码欧美| 国产精品久久久久久久久免费看| 国产资源在线观看入口av| 精品中文字幕在线观看| 日本三级视频在线观看| 亚洲性线免费观看视频成熟| 四虎影视在线观看2413| 亚洲国模精品一区| 国模无码一区二区三区| 日韩一区二区三区视频| 国产精品人人爽| 欧美妇女性影城| 一个人看的www日本高清视频| 91电影在线观看| 无码人妻av一区二区三区波多野| 精品福利在线视频| 日韩成人免费观看| 五月天亚洲婷婷| 日韩欧美国产亚洲| 天天综合日日夜夜精品| 99精品视频99| 色先锋久久av资源部| 国产三级精品三级在线观看| 狠狠综合久久av一区二区小说| 日韩精品一区二区在线播放| 精品福利免费观看| 五月天婷婷激情| 欧洲中文字幕精品| 亚洲天堂免费av| 欧美日本免费一区二区三区| 怡红院男人的天堂| 欧美日韩亚洲综合在线| 一区二区三区日| 欧美一级理论性理论a| 精品人妻伦一二三区久久| 亚洲第一av网站| 日本一级在线观看| 在线观看欧美日韩国产| 人人干在线视频| 欧美猛少妇色xxxxx| 波多野结衣视频一区二区| 国产99久久精品一区二区永久免费 | 欧美视频在线观看一区二区| 一级黄色录像大片| 日韩亚洲欧美一区| 婷婷开心激情网| 国产一区二区三区在线视频| 日本三级在线播放完整版| 久久91精品国产91久久跳| 成人免费网站观看| 国产精品久久久久久av下载红粉 | aa视频在线观看| 2023亚洲男人天堂| 日韩av黄色| 国产精品一区二区三区在线| 亚洲区小说区图片区qvod| 亚洲午夜精品一区二区三区| 亚洲欧美文学| 免费观看精品视频| 久草在线在线精品观看| 波多野结衣办公室双飞 | 亚洲第一区中文字幕| 国产午夜在线观看| 久久成人精品一区二区三区| wwww在线观看免费视频| 国产成人精品视频| 日本精品在线观看| 欧美日本国产精品| 亚洲草久电影| 一本久道中文无码字幕av| 国产乱妇无码大片在线观看| asian性开放少妇pics| 亚洲婷婷综合色高清在线| 日本中文字幕在线免费观看| 欧美日韩高清不卡| 视频福利在线| 欧美精品性视频| 懂色aⅴ精品一区二区三区| 粉嫩av一区二区三区免费观看| 国产一区二区三区日韩精品| 欧美一区二区视频在线播放| 日韩高清在线一区| 亚洲一区二区三区黄色| 国产精品丝袜91| 欧美日韩一二三四区| 91精品国产免费| 国产日本在线观看| 88xx成人精品| 亚洲视频一起| 亚洲一区三区电影在线观看| 亚洲综合不卡| 国产日韩视频一区| 亚洲视频免费观看| 中文字幕在线观看第二页| 国产婷婷97碰碰久久人人蜜臀| 黄页在线观看免费| 91超碰在线电影| 天天揉久久久久亚洲精品| 日本成人中文字幕在线| 91蝌蚪porny| 青青操免费在线视频| 精品国产亚洲一区二区三区在线观看| 欧美jizzhd欧美| 国产日韩欧美在线看| 精品欧美久久| 99热手机在线| 欧美激情一区二区三区在线| 亚洲国产成人无码av在线| 亚洲精品99久久久久中文字幕| 欧美人动性xxxxz0oz| 99re国产视频| 国语精品一区| 手机免费看av片| 亚洲国产成人av好男人在线观看| 国产黄色美女视频| 久久综合久久88| 精品视频一区二区三区在线观看| 一区二区三区一级片| 国产一区二区三区在线观看免费| 天海翼在线视频| 日韩一区二区三区视频在线| 亚洲综合图区| 国产精品国产亚洲精品看不卡15| 欧美日韩第一区| 人妻av一区二区三区| 亚洲一区二区三区四区的| 亚洲黄色小说网址| 国内精品小视频| 啪啪国产精品| 免费在线观看毛片网站| 国产欧美一区二区精品秋霞影院| 加勒比在线一区| 久久精品99久久久香蕉| 高清久久一区| 久久久久久av无码免费网站下载| 国产成人鲁色资源国产91色综| 久久婷婷综合国产| 日韩av在线天堂网| 快播电影网址老女人久久| 亚洲精品视频一区二区三区| 久久精品国产99国产精品| 少妇影院在线观看| 亚洲精品v欧美精品v日韩精品| av电影一区| 亚洲一区二区在线看| 国产一区二区不卡| 日韩美女视频网站| 国产午夜精品美女视频明星a级| 日本精品久久| 嫩草影院中文字幕| 久久一二三国产| 一区二区三区免费观看视频| 欧美福利视频网站| 精品久久久久中文字幕小说 | 久久影院一区二区三区| 亚洲精品蜜桃久久久久久| 久久婷婷久久一区二区三区| 在线观看日韩一区二区| 欧美国产日韩中文字幕在线| 欧美电影在线观看免费| 亚洲黄色av网址| 亚洲在线中文字幕| 国产永久av在线| 爱情岛论坛亚洲入口| 日韩激情视频在线观看| 久久久.www| 亚洲色图第三页| 日本一区二区三区播放| 欧美激情成人网| 亚洲乱码中文字幕| 成人在线免费观看| 精品久久久久亚洲| 亚洲一级在线播放| 在线观看日韩高清av| 男女在线观看视频|