日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

SSM框架-Spring(一)

發(fā)布時(shí)間:2023/12/18 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SSM框架-Spring(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

1 Spring啟示錄

1.1 OCP開閉原則

1.2 依賴倒置原則DIP

1.3 控制反轉(zhuǎn)IoC

2 Spring概述

2.1 Spring簡(jiǎn)介

2.2 Spring8大模塊

2.3 Spring特點(diǎn)

2.4 本次學(xué)習(xí)使用軟件版本

3 Spring入門程序

3.1 Spring下載

3.2 第一個(gè)Spring程序

3.3 第一個(gè)spring程序的細(xì)節(jié)

3.4?Spring6啟用Log4j2日志框架

4 spring對(duì)IoC的實(shí)現(xiàn)

4.1 set注入

4.2 構(gòu)造注入

4.3 set注入專題

4.3.1 注入內(nèi)部bean和外部bean

4.3.2 注入簡(jiǎn)單類型

4.3.3 級(jí)聯(lián)屬性賦值

4.3.4 數(shù)組注入

4.3.5 集合注入

4.3.6 注入null和空字符串

4.3.7 特殊字符的注入

4.4 p命名空間注入

4.5 c命名空間注入

4.6 util命名空間

4.7 基于XML的自動(dòng)裝配

4.7.1 根據(jù)名稱自動(dòng)裝配

4.7.2 根據(jù)類型自動(dòng)裝配

4.8?Spring引入外部屬性配置文件

5 Bean的作用域

5.1 singleton

5.2 prototype

5.3 其它scope

6 GoF工廠設(shè)計(jì)模式

6.1 工廠模式三種形態(tài)

6.2 簡(jiǎn)單工廠模式

6.3 工廠方法模式

6.4 抽象工廠模式(了解)

7 Bean的實(shí)例化方式

7.1 通過(guò)構(gòu)造方法實(shí)例化

7.2 通過(guò)簡(jiǎn)單工廠模式實(shí)例化

7.3 通過(guò)factory-bean實(shí)例化

7.4 通過(guò)FactoryBean接口實(shí)例化

7.5 BeanFactory和FactoryBean的區(qū)別

7.5.1 BeanFactory

7.5.2 FactoryBean

7.6 注入自定義Date

8 Bean的聲明周期

8.1 什么是Bean的生命周期

8.2 為什么要知道Bean的生命周期

8.3 Bean的聲明周期之五步

8.4 Bean生命周期之7步

8.5 Bean生命周期之10步

8.6 Bean的作用域不同,管理方式不同

9 Bean的循環(huán)依賴問(wèn)題

9.1 什么是Bean的循環(huán)依賴

9.2 singleton下的set注入產(chǎn)生的循環(huán)依賴

9.3 prototype下的set注入產(chǎn)生的循環(huán)依賴

9.4 singleton下的構(gòu)造注入產(chǎn)生的循環(huán)依賴

10 回顧反射機(jī)制

10.1 分析方法四要素

10.2 使用反射機(jī)制調(diào)用方法

10.3 假設(shè)知道屬性名


1 Spring啟示錄

我們之前學(xué)過(guò)mvc設(shè)計(jì)模式,這種模式可以有效的降低代碼的耦合度,提高擴(kuò)展力,我們?cè)賹懸粋€(gè)這樣的模式,代碼如下:

在創(chuàng)建maven項(xiàng)目前我們可以先設(shè)置如下

package com.itzw.spring6.dao.impl;import com.itzw.spring6.dao.UserDao;public class UserDaoImplForMySQL implements UserDao {public void select() {System.out.println("正在連接數(shù)據(jù)庫(kù)。。。");} } package com.itzw.spring6.service.impl;import com.itzw.spring6.dao.UserDao; import com.itzw.spring6.dao.impl.UserDaoImplForMySQL; import com.itzw.spring6.service.UserService;public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImplForMySQL();public void login() {userDao.select();} } package com.itzw.spring6.servlet;import com.itzw.spring6.service.UserService; import com.itzw.spring6.service.impl.UserServiceImpl;public class UserServlet {private UserService userService = new UserServiceImpl();public void loginRequest(){userService.login();} }

以上大概就是我們之前學(xué)的mvc架構(gòu)模式,分為表示層、業(yè)務(wù)邏輯層、持久層。而其中UserServlet依賴了具體的UserServiceImpl,UserServiceImpl依賴了具體的UserDaoImplForMySQL。

假如我們不想連接mysql數(shù)據(jù)庫(kù)了,我們想連接Oracle數(shù)據(jù)庫(kù),我們就要修改UserServiceImpl中的代碼。

1.1 OCP開閉原則

什么是OCP?

  • OCP是軟件七大開發(fā)原則當(dāng)中最基本的一個(gè)原則。對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉
  • 其中OCP原則是最核心的最基本的,其它六個(gè)原則都是為了這個(gè)原則服務(wù)的
  • OCP開閉原則的核心是:當(dāng)我們?cè)跀U(kuò)展系統(tǒng)功能的時(shí)候,沒(méi)有修改以前寫好的代碼那么就是符合OCP原則的,反之不符合這個(gè)原則

如上圖可以很明顯的看出上層是依賴下層的,下面改動(dòng)上面必然改動(dòng),這樣同樣違背了另一個(gè)開發(fā)原則:依賴倒置原則

1.2 依賴倒置原則DIP

依賴倒置原則(Dependence Inversion Principe),倡導(dǎo)面向接口編程,面向抽象編程,不要面向具體編程,讓上層不再依賴下層,下層改動(dòng)上層不需要改動(dòng),這樣大大降低耦合度,耦合度低了,擴(kuò)展力就強(qiáng)了,同時(shí)代碼復(fù)用性也會(huì)增強(qiáng)(軟件七大開發(fā)原則都在為解耦合服務(wù))

那我們可能有疑問(wèn),這不就是面向接口編程的嗎?確實(shí),是這樣的,但是不完全是,我們雖然都是調(diào)用接口中的方法,但是我們是通過(guò)new 對(duì)象,new一個(gè)具體的接口實(shí)現(xiàn)類,如下:

如下才是完全面向接口,完全符合依賴倒置原則:

但是如果這樣編程userDao是null,那么就會(huì)出現(xiàn)空指針異常,確實(shí)是這樣。這也就是我們接下來(lái)要解決的問(wèn)題。

1.3 控制反轉(zhuǎn)IoC

控制反轉(zhuǎn)(Inversion of Control),是面向?qū)ο缶幊痰囊环N設(shè)計(jì)思想,可以用來(lái)降低代碼的耦合度,符合依賴倒置原則??刂品崔D(zhuǎn)的核心是:將對(duì)象的創(chuàng)建權(quán)交出去,將對(duì)象和對(duì)象之間的關(guān)系管理權(quán)交出去,由第三方容器負(fù)責(zé)創(chuàng)建與維護(hù)。

我們要學(xué)的Spring框架實(shí)現(xiàn)了控制反轉(zhuǎn)這種思想,Spring框架可以幫我們new 對(duì)象,還可以幫我們維護(hù)對(duì)象與對(duì)象之間的關(guān)系

控制反轉(zhuǎn)常用的實(shí)現(xiàn)方法:依賴注入(Dependency Injection,簡(jiǎn)稱DI)

依賴注入DI,包括兩種常見的 方式:

  • 第一種:set方法注入(執(zhí)行set方法給屬性賦值)
  • 第二種:構(gòu)造方法注入

IoC是一種全新的設(shè)計(jì)模式,但是理論和時(shí)間成熟較晚,并沒(méi)有包含在GoF中(GoF是23中設(shè)計(jì)模式)

2 Spring概述

2.1 Spring簡(jiǎn)介

來(lái)自百度百科:

  • Spring是一個(gè)開源框架,它由Rod Johnson創(chuàng)建。它是為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的。
  • 從簡(jiǎn)單性、可測(cè)試性和松耦合的角度而言,任何Java應(yīng)用都可以從Spring中受益。
  • Spring是一個(gè)輕量級(jí)的控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架。
  • Spring最初的出現(xiàn)是為了解決EJB臃腫的設(shè)計(jì),以及難以測(cè)試等問(wèn)題。
  • Spring為簡(jiǎn)化開發(fā)而生,讓程序員只需關(guān)注核心業(yè)務(wù)的實(shí)現(xiàn),盡可能的不再關(guān)注非業(yè)務(wù)邏輯代碼(事務(wù)控制,安全日志等)。

2.2 Spring8大模塊

注意:Spring5版本之后是8個(gè)模塊。在Spring5中新增了WebFlux模塊。

Spring Core模塊:這是Spring框架最基礎(chǔ)的部分,它提供了依賴注入特征來(lái)實(shí)現(xiàn)容器對(duì)Bean的管理。

2.3 Spring特點(diǎn)

  • 輕量
  • 控制反轉(zhuǎn)
  • 面向切面
  • 容器
  • 框架

2.4 本次學(xué)習(xí)使用軟件版本

  • IDEA:2021.2.3
  • JDK:java17(Spring6要求JDK最低版本是java17)
  • Maven:3.3.9
  • Spring:6.0.0-M2
  • Junit:4.13.2

3 Spring入門程序

3.1 Spring下載

官網(wǎng)地址:Spring | Home

官網(wǎng)地址(中文):Spring 中文網(wǎng) 官網(wǎng)

以上兩個(gè)地址都可以下載,不過(guò)我們可以直接使用maven下載依賴,就像mybatis一樣

3.2 第一個(gè)Spring程序

前期準(zhǔn)備:在idea中創(chuàng)建一個(gè)maven模塊,這個(gè)我們?cè)缫言O(shè)置好,直接用即可

第一步:添加spring context依賴

<repositories><!--spring里程碑版本的倉(cāng)庫(kù)--><repository><id>repository.spring.milestone</id><name>Spring Milestone Repository</name><url>https://repo.spring.io/milestone</url></repository></repositories><dependencies><!--spring context依賴--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.0-M2</version></dependency></dependencies>

注意:打包方式為jar

當(dāng)加入spring context依賴之后,會(huì)關(guān)聯(lián)引入其它依賴

  • spring aop:面向切面編程
  • spring beans:IoC核心
  • spring core:spring核心工具包
  • spring jcl:spring的日志包
  • spring expression:spring表達(dá)式

第二步:添加junit依賴

<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency>

第三步:定義bean:User

package com.itzw.spring6.bean;/*** 封裝用戶信息*/ public class User { }

第四步:編寫spring配置文件spring.xml,放在類的根目錄下也就是resources目錄

我們直接右擊resources就可以創(chuàng)建idea提供的文件模板:

在配置文件中進(jìn)行bean配置:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userBean" class="com.itzw.spring6.bean.User"></bean></beans>

需要注意的是:這個(gè)文件最好放在類路徑下,方便移植

bean標(biāo)簽的兩個(gè)重要屬性:id:這是bean的身份證,不能重復(fù),是唯一標(biāo)識(shí);class:必須填寫類的全路徑,全限定類名。

第五步:編寫測(cè)試程序

package com.itzw.spring6.test;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Spring6Test {@Testpublic void testFirst(){//第一步:獲取spring容器對(duì)象//ApplicationContext是一個(gè)接口,接口下有很多實(shí)現(xiàn)類,其中有一個(gè)叫做:ClassPathXmlApplicationContext//ClassPathXmlApplicationContext 專門從類路徑下加載spring配置文件的一個(gè)spring上下文對(duì)象//運(yùn)行這行代碼就相當(dāng)于啟動(dòng)了spring容器,解析spring.xml文件,并且實(shí)例化所有的bean對(duì)象,放到spring容器當(dāng)中ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//第二步:根據(jù)bean的id從spring容器中獲取這個(gè)對(duì)象Object userBean = applicationContext.getBean("userBean");System.out.println(userBean);}}

測(cè)試結(jié)果:

3.3 第一個(gè)spring程序的細(xì)節(jié)

(1)bean的id不能重復(fù):

<bean id="userBean" class="com.itzw.spring6.bean.User"></bean><bean id="userBean" class="com.itzw.spring6.bean.Vip"></bean>

(2)底層是怎樣創(chuàng)建對(duì)象的:

我們?cè)赨ser類中寫上無(wú)參構(gòu)造:

public class User {public User(){System.out.println("這是User類的無(wú)參構(gòu)造");} }

測(cè)試:

如果只有有參構(gòu)造沒(méi)有無(wú)參呢?

public class User { /* public User(){System.out.println("這是User類的無(wú)參構(gòu)造");}*/public User(String name){System.out.println("這是User類的有參構(gòu)造");} }

經(jīng)過(guò)測(cè)試:spring是通過(guò)調(diào)用類的無(wú)參構(gòu)造來(lái)創(chuàng)建對(duì)象的,所以要想讓spring給你創(chuàng)建對(duì)象,必須保證無(wú)參構(gòu)造方法是存在的

spring是通過(guò)反射機(jī)制調(diào)用無(wú)參構(gòu)造方法創(chuàng)建對(duì)象

(3)創(chuàng)建好的對(duì)象存儲(chǔ)在map集合中

(4)Spring配置文件的名字可以隨意改

(5)spring配置文件可以創(chuàng)建多個(gè)

我們?cè)賱?chuàng)建一個(gè)spring配置文件,配置bean的信息

我們直接在ClassPathXmlApplicationContext構(gòu)造方法參數(shù)上傳遞路徑即可,不需要再new一個(gè)ClassPathXmlApplicationContext對(duì)象,為什么呢?通過(guò)源碼查看是可以傳多個(gè)的?

(6)配置文件中的類必須是自定義的嗎

不是,可以是jdk自帶的類,如下:

<bean id="dateBean" class="java.util.Date"></bean> Object dateBean = applicationContext.getBean("dateBean");System.out.println(dateBean);

可以直接輸出當(dāng)前日期

經(jīng)測(cè)試,spring配置文件中的bean可以是任意類,只要它不是抽象的并且有無(wú)參構(gòu)造

(7)執(zhí)行g(shù)etBean方法時(shí)傳入的參數(shù)不存在會(huì)報(bào)異常

(8)getBean方法返回類型問(wèn)題

默認(rèn)返回類型是Object,當(dāng)然我們可以強(qiáng)轉(zhuǎn),但是有沒(méi)有別的辦法,

User userBean1 = applicationContext.getBean("userBean", User.class);

可以通過(guò)第二個(gè)參數(shù)返回bean的類型

3.4?Spring6啟用Log4j2日志框架

從spring5之后,Spring框架支持集成的日志框架是Log4j2.如何啟用日志框架:

第一步:引入log4j2的依賴:

<!--log4j2的依賴--> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.19.0</version> </dependency>

第二步:在類的根路徑下提供log4j2.xml配置文件(文件名固定為:log4j2.xml,文件必須放到類根路徑下。)

<?xml version="1.0" encoding="UTF-8"?><configuration><loggers><!--level指定日志級(jí)別,從低到高的優(yōu)先級(jí):ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF--><root level="DEBUG"><appender-ref ref="spring6log"/></root></loggers><appenders><!--輸出日志信息到控制臺(tái)--><console name="spring6log" target="SYSTEM_OUT"><!--控制日志輸出的格式--><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/></console></appenders></configuration>

這樣我們的輸出信息就有日志信息了:?

但是我們自己怎么使用日志信息呢?

@Testpublic void testLog(){//第一步:創(chuàng)建日志記錄對(duì)象//獲取Spring6Test類的日志記錄對(duì)象,也就是說(shuō)只要是Spring6Test類中的代碼記錄日志的話,就輸出日志信息Logger logger = LoggerFactory.getLogger(Spring6Test.class);//第二步:記錄日志,根據(jù)不同級(jí)別來(lái)輸出日志logger.info("我是一條信息");logger.debug("我是一個(gè)調(diào)試信息");logger.error("我是一條錯(cuò)誤信息");}

4 spring對(duì)IoC的實(shí)現(xiàn)

前面我們講過(guò)我們可以使用依賴注入實(shí)現(xiàn)控制反轉(zhuǎn)??刂品崔D(zhuǎn)的思想是將對(duì)象的創(chuàng)建權(quán)交出去,交給第三方容器。

實(shí)現(xiàn)依賴注入主要有兩個(gè)方式:set注入和構(gòu)造注入

4.1 set注入

我們創(chuàng)建一個(gè)新的模塊,我們先像之前那樣創(chuàng)建一個(gè)dao文件和一個(gè)service文件,不過(guò)這次在service目錄下我們不new新的dao對(duì)象,如下:

package com.itzw.spring6.dao;import org.slf4j.Logger; import org.slf4j.LoggerFactory;public class UserDao {private static final Logger logger = LoggerFactory.getLogger(UserDao.class);public void insert(){logger.info("正在插入信息。。");} } package com.itzw.spring6.service;import com.itzw.spring6.dao.UserDao;public class UserService {UserDao userDao;public void saveUser(){userDao.insert();} } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDaoBean" class="com.itzw.spring6.dao.UserDao"></bean><bean id="userServiceBean" class="com.itzw.spring6.service.UserService"></bean> </beans> public class SpringTest {@Testpublic void testInjectBySet(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");UserService userServiceBean = applicationContext.getBean("userServiceBean", UserService.class);userServiceBean.saveUser();} }

但是這樣測(cè)試結(jié)果顯然是出錯(cuò)的,dao對(duì)象是null的

我們使用set注入的方式來(lái)實(shí)現(xiàn)控制反轉(zhuǎn):

我們需要提供一個(gè)set方法,spring會(huì)調(diào)用這個(gè)set方法給userDao屬性賦值,我們直接使用idea工具生成這個(gè)set方法即可

我們現(xiàn)在需要service調(diào)用set方法,這就要借助spring,我們?cè)赽ean標(biāo)簽配置property標(biāo)簽,其中name屬性就是用來(lái)傳set方法的,name屬性名指定格式為set方法的方法名去掉set,然后剩下的單詞首字母小寫。這就實(shí)現(xiàn)了UserService類調(diào)用set方法,但是我們還需要傳值,傳一個(gè)UserDao對(duì)象的值,因?yàn)樯厦嫖覀兣渲妙恥serDao的bean標(biāo)簽,我們直接把它的id值傳給property中的ref屬性即可這就完成了傳值。如下:

配置好后再次測(cè)試,測(cè)試成功。

4.2 構(gòu)造注入

我們多建一個(gè)dao文件,在service文件中直接用idea自動(dòng)生成構(gòu)造方法

package com.itzw.spring6.service;import com.itzw.spring6.dao.UserDao; import com.itzw.spring6.dao.VipDao;public class AccountService {UserDao userDao;VipDao vipDao;public AccountService(UserDao userDao, VipDao vipDao) {this.userDao = userDao;this.vipDao = vipDao;}public void test(){userDao.insert();vipDao.delete();} }

在spring配置文件中配置如下,和set方法差不多

<bean id="userDaoBean" class="com.itzw.spring6.dao.UserDao"></bean><bean id="vipDaoBean" class="com.itzw.spring6.dao.VipDao"></bean><!--構(gòu)造注入--><bean id="accountServiceBean" class="com.itzw.spring6.service.AccountService"><!--index屬性指定參數(shù)下標(biāo),第一個(gè)參數(shù)是0,第二個(gè)參數(shù)是1,第三個(gè)參數(shù)是3,依次。。ref指定注入的bean的id--><!--<constructor-arg index="0" ref="userDaoBean"/><constructor-arg index="1" ref="vipDaoBean"/>--><!--我們還有別的方法進(jìn)行構(gòu)造注入--><constructor-arg name="userDao" ref="userDaoBean"/><constructor-arg name="vipDao" ref="vipDaoBean"/></bean>

測(cè)試即可。

4.3 set注入專題

以為set注入使用的較多,我們使用set注入來(lái)學(xué)習(xí)下面的內(nèi)容

4.3.1 注入內(nèi)部bean和外部bean

我們之前使用的set注入就是注入外部bean,那什么是注入內(nèi)部bean呢?

在property中嵌套bean標(biāo)簽就是內(nèi)部bean。這樣麻煩了一點(diǎn),我們一般不用這種方式,我們還是用之前的方式?

<bean id="userDaoBean" class="com.itzw.spring6.dao.UserDao"/><bean id="orderDaoBean" class="com.itzw.spring6.service.OrderDao"><property name="userDao"><bean class="com.itzw.spring6.dao.UserDao"/></property></bean>

4.3.2 注入簡(jiǎn)單類型

我們之前注入的數(shù)據(jù)都不是簡(jiǎn)單類型,對(duì)象屬性都是一個(gè)對(duì)象,我們現(xiàn)在注入屬性是一個(gè)數(shù)據(jù)的。

我們寫一個(gè)類,寫上屬性,創(chuàng)建set方法和toString方法:

package com.itzw.spring6.beans;public class User {private String name;private int age;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';} }

編寫spring配置文件:

<!--簡(jiǎn)單類型注入--><bean id="userBean" class="com.itzw.spring6.beans.User"><property name="age" value="24"/><property name="name" value="張麻子"/></bean>

在這里name屬性依然是set方法,但是我們給set方法參數(shù)傳值就只要傳簡(jiǎn)單的數(shù)據(jù)就可以了,所以我們使用value來(lái)賦值。

測(cè)試:結(jié)果如下:

那么簡(jiǎn)單類型包括哪些呢?

public static boolean isSimpleValueType(Class<?> type) {return (Void.class != type && void.class != type &&(ClassUtils.isPrimitiveOrWrapper(type) ||Enum.class.isAssignableFrom(type) ||CharSequence.class.isAssignableFrom(type) ||Number.class.isAssignableFrom(type) ||Date.class.isAssignableFrom(type) ||Temporal.class.isAssignableFrom(type) ||URI.class == type ||URL.class == type ||Locale.class == type ||Class.class == type));}

我們查看源碼分析:BeanUtils類,得知簡(jiǎn)單類型有:

  • 基本數(shù)據(jù)類型
  • 基本數(shù)據(jù)類型對(duì)應(yīng)包裝類
  • String或其他的CharSequence子類
  • Number子類
  • Date子類
  • Enum子類
  • URI
  • URL
  • Temporal子類
  • Locale
  • Class
  • 另外還包括以上簡(jiǎn)單值類型對(duì)應(yīng)的數(shù)據(jù)類型

簡(jiǎn)單類型注入的經(jīng)典應(yīng)用:

給數(shù)據(jù)源的屬性賦值,比如我們經(jīng)常使用的數(shù)據(jù)庫(kù)的連接:

private String driver;private String url;private String username;private String password;@Overridepublic String toString() {return "MyDataSource{" +"driver='" + driver + '\'' +", url='" + url + '\'' +", username='" + username + '\'' +", password='" + password + '\'' +'}';}public void setDriver(String driver) {this.driver = driver;}public void setUrl(String url) {this.url = url;}public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;} <!--簡(jiǎn)單類型注入的應(yīng)用--><bean id="dataSourceBean" class="com.itzw.spring6.jdbc.MyDataSource"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://172.0.0.1:3306/spring"/><property name="username" value="root"/><property name="password" value="123456"/></bean> @Testpublic void testSimple2(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");Object dataSourceBean = applicationContext.getBean("dataSourceBean");System.out.println(dataSourceBean);}

你們可以把簡(jiǎn)單類型都測(cè)試一遍,那我不測(cè)了,我不打擾我走了哈哈。

4.3.3 級(jí)聯(lián)屬性賦值

也就是我們熟悉的套娃賦值,就是一個(gè)類的屬性有另一個(gè)類。我們先用我們學(xué)過(guò)的方式賦值:

package com.itzw.spring6.dao;public class Clazz {private String name;public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Clazz{" +"name='" + name + '\'' +'}';} } package com.itzw.spring6.dao;public class Student {private String name;private int age;private Clazz clazz;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", clazz=" + clazz +'}';}public void setClazz(Clazz clazz) {this.clazz = clazz;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;} } <!--級(jí)聯(lián)屬性賦值--><bean class="com.itzw.spring6.dao.Student" id="studentBean"><property name="name" value="張麻子"/><property name="age" value="34"/><property name="clazz" ref="clazzBean"/></bean><bean class="com.itzw.spring6.dao.Clazz" id="clazzBean"><property name="name" value="高三一班"/></bean> @Testpublic void testCascade(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");Student studentBean = applicationContext.getBean("studentBean", Student.class);System.out.println(studentBean);}

以上是我們學(xué)過(guò)的方式,測(cè)試結(jié)果:

我們使用級(jí)聯(lián)屬性賦值:

<!--級(jí)聯(lián)屬性賦值--><bean class="com.itzw.spring6.dao.Student" id="studentBean"><property name="name" value="張麻子"/><property name="age" value="34"/><property name="clazz" ref="clazzBean"/><!--級(jí)聯(lián)屬性賦值--><property name="clazz.name" value="高三二班"/></bean><bean class="com.itzw.spring6.dao.Clazz" id="clazzBean"></bean>

使用這種方式我們需要給clazz屬性構(gòu)造get方法,這種方式顯得很麻煩,還不如之前的方法。

4.3.4 數(shù)組注入

首先簡(jiǎn)單類型的數(shù)組注入:

package com.itzw.spring6.dao;import java.util.Arrays;public class Huang {private String[] hobbies;public void setHobbies(String[] hobbies) {this.hobbies = hobbies;}@Overridepublic String toString() {return "Huang{" +"hobbies=" + Arrays.toString(hobbies) +'}';} } <!--數(shù)組注入--><bean id="huang" class="com.itzw.spring6.dao.Huang"><property name="hobbies"><array><value>抽煙</value><value>喝酒</value><value>燙頭</value></array></property></bean> @Testpublic void testArray(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");Huang huang = applicationContext.getBean("huang", Huang.class);System.out.println(huang);}

如果數(shù)組元素是非簡(jiǎn)單類型呢?

<bean class="com.itzw.spring6.dao.Woman" id="w1"><property name="name" value="小花"/></bean><bean class="com.itzw.spring6.dao.Woman" id="w2"><property name="name" value="小美"/></bean><bean class="com.itzw.spring6.dao.Woman" id="w3"><property name="name" value="小麗"/></bean><!--數(shù)組注入--><bean id="huang" class="com.itzw.spring6.dao.Huang"><property name="hobbies"><array><value>抽煙</value><value>喝酒</value><value>燙頭</value></array></property><property name="womens"><array><ref bean="w1"/><ref bean="w2"/><ref bean="w3"/></array></property></bean>

4.3.5 集合注入

注意的是:list集合有序和重復(fù),set集合無(wú)序不重復(fù)

package com.itzw.spring6.dao;import java.util.List; import java.util.Set;public class Person {List names;Set addrs;public void setNames(List names) {this.names = names;}public void setAddrs(Set addrs) {this.addrs = addrs;}@Overridepublic String toString() {return "Person{" +"names=" + names +", addrs=" + addrs +'}';} } <!--集合注入set和list--><bean class="com.itzw.spring6.dao.Person" id="person"><property name="names"><list><value>張三</value><value>李四</value><value>張麻子</value><value>黃四郎</value><value>張三</value></list></property><property name="addrs"><set><value>徐州市銅山區(qū)</value><value>徐州市云龍區(qū)</value><value>徐州市銅山區(qū)</value><value>徐州市銅山區(qū)</value></set></property></bean> @Testpublic void testListAndSet(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");Person person = applicationContext.getBean("person", Person.class);System.out.println(person);}

map集合,有鍵值對(duì):

<property name="tel"><map><!--一個(gè)entry就表示一個(gè)鍵值對(duì)--><entry key="tel1" value="110"/><entry key="tel2" value="119"/><entry key="tel3" value="120"/></map></property>

properties集合本質(zhì)上也是map集合,但是它的注入方式不一樣

<property name="properties"><props><prop key="username">root</prop><prop key="password">1234</prop></props></property>

4.3.6 注入null和空字符串

<!--注入null和空字符串--><bean class="com.itzw.spring6.dao.Man" id="man"><!--<property name="name" value="張麻子"></property>--><property name="name"><!--手動(dòng)賦值為null--><null></null></property><!--賦值為空字符串--><!--第一種方式--><!--<property name="addr" value=""/>--><!--第二種方式--><property name="addr"><value/></property></bean>

4.3.7 特殊字符的注入

XML中有5個(gè)特殊字符,分別是:<、>、'、"、&。

這些字符直接出現(xiàn)在xml當(dāng)中會(huì)報(bào)錯(cuò):

解決方式有兩種:

  • 第一種:使用轉(zhuǎn)義字符代替
  • 第二種:將含有特殊符號(hào)的字符串放到:<![CDATA[]]> 當(dāng)中。因?yàn)榉旁贑DATA區(qū)中的數(shù)據(jù)不會(huì)被XML文件解析器解析。

特殊字符對(duì)應(yīng)的轉(zhuǎn)移字符如下:

特殊字符

轉(zhuǎn)義字符

>

&gt;

<

&lt;

'

&apos;

"

&quot;

&

&amp;

<!--特殊字符的注入--><bean class="com.itzw.spring6.dao.Zhou" id="zhou"><!--第一種方式--><property name="name" value="1 &lt; 2"/><!--第二種方式--><property name="addr"><value><![CDATA[2<3]]></value></property></bean>

4.4 p命名空間注入

使用p命名空間注入可以簡(jiǎn)化配置,使用前提是:

  • 要在xml配置文件上方添加配置信息:xmlns:p="http://www.springframework.org/schema/p"
  • p命名空間注入是基于set方法的,要提供set方法

其實(shí)p命名空間注入就是代替set注入的

<bean class="com.itzw.spring6.dao.Dog" id="dog" p:name="小花" p:age="2"/>

4.5 c命名空間注入

c命名空間注入是用來(lái)簡(jiǎn)化構(gòu)造注入的,那么使用前提是:

  • 需要在xml配置文件頭部添加信息:xmlns:c="http://www.springframework.org/schema/c"
  • 需要提供構(gòu)造方法。?
<bean class="com.itzw.spring6.dao.Cat" id="cat" c:name="小貓" c:age="2"/>

注意:不管是p命名注入還是c命名注入都可以注入非簡(jiǎn)單類型

4.6 util命名空間

使用util命名空間可以讓配置復(fù)用,使用前提是:在spring配置文件頭部添加如下信息:

比如我想給多個(gè)java文件都傳輸jdbc連接的信息,它們的信息都是一樣的,這時(shí)我們就可以將這段信息使用util命名空間方式

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"><util:properties id="prop"><prop key="driver">com.mysql.cj.jdbc.Driver</prop><prop key="url">jdbc:mysql://localhost:3306/spring</prop><prop key="username">root</prop><prop key="password">123</prop></util:properties><bean class="com.itzw.spring6.jdbc.MyDataSource2" id="ds2"><property name="properties" ref="prop"/></bean><bean class="com.itzw.spring6.jdbc.MyDataSource3" id="ds3"><property name="properties" ref="prop"/></bean> </beans>

4.7 基于XML的自動(dòng)裝配

Spring還可以完成自動(dòng)化的注入,自動(dòng)化注入又被稱為自動(dòng)裝配。它可以根據(jù)名字進(jìn)行自動(dòng)裝配,也可以根據(jù)類型進(jìn)行自動(dòng)裝配。

4.7.1 根據(jù)名稱自動(dòng)裝配

回憶之前的業(yè)務(wù)邏輯層和持久層之間的連接,其中spring配置信息如下:

<bean class="com.itzw.spring6.dao.UserDao" id="userDaoBean"></bean><bean class="com.itzw.spring6.service.OrderDao" id="orderDao"><property name="userDao" ref="userDaoBean"/></bean>

我們使用自動(dòng)裝配:

<bean class="com.itzw.spring6.dao.UserDao" id="userDao"/><bean class="com.itzw.spring6.service.OrderDao" id="orderDao" autowire="byName"/>

在orderDao的bean中添加autowire,值設(shè)為byName表示通過(guò)名稱進(jìn)行自動(dòng)裝配

OrderDao類中有一個(gè)UserDao屬性,set方法為setUserDao,而UserDao的bean的id為userDao,恰好和OrderDao中的set方法對(duì)應(yīng)。滿足這些才能自動(dòng)裝配

也就是說(shuō)需要set方法名和想要注入的類的bean的id值對(duì)應(yīng)上才行

4.7.2 根據(jù)類型自動(dòng)裝配

<bean class="com.itzw.spring6.dao.UserDao"/><bean class="com.itzw.spring6.service.OrderDao" id="orderDao" autowire="byType"/>

這樣連id值都不需要傳了,直接就能識(shí)別自己想要的類。但是也有缺陷,不能出現(xiàn)多個(gè)同一個(gè)類的bean,這樣它就識(shí)別不出哪個(gè)是自己需要的了。

值得注意的是:不管是根據(jù)name自動(dòng)裝配還是類型自動(dòng)裝配都是基于set注入實(shí)現(xiàn)的,也就是都需要有set方法,否則不行。

從這自動(dòng)裝配我們可以看出來(lái),尤其是根據(jù)類型自動(dòng)裝配可讀性 很差而且有限制,不如我們用原始方法,沒(méi)有方便多少反而看的 蛋疼。

4.8?Spring引入外部屬性配置文件

我們連接數(shù)據(jù)庫(kù)的時(shí)候需要配置一些信息,我們能像之前學(xué)習(xí)一樣把這些配置信息放在一個(gè)文件中然后引入到xml文件中嗎?當(dāng)然可以。

第一步:寫一個(gè)數(shù)據(jù)源類 提供相關(guān)屬性:

package com.itzw.spring6.jdbc;import javax.sql.DataSource; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.logging.Logger;public class MyDataSource implements DataSource {private String driver;private String url;private String username;private String password;@Overridepublic String toString() {return "MyDataSource{" +"driver='" + driver + '\'' +", url='" + url + '\'' +", username='" + username + '\'' +", password='" + password + '\'' +'}';}public void setDriver(String driver) {this.driver = driver;}public void setUrl(String url) {this.url = url;}public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;}@Overridepublic Connection getConnection() throws SQLException {return null;}//...}

第二步:在類路徑下建立jdbc.properties文件并配置信息:

driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/spring username=root password=123

第三步:在spring配置文件中引入context命名空間

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"></beans>

第四步:在spring配置文件中使用:

使用context標(biāo)簽引入jdbc配置文件

<context:property-placeholder location="jdbc.properties"/><bean class="com.itzw.spring6.jdbc.MyDataSource" id="ds"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></bean>

但需要注意的是,${}中的值會(huì)默認(rèn)先去系統(tǒng)找對(duì)應(yīng)的值,比如username會(huì)去系統(tǒng)找,極可能輸出的結(jié)果是系統(tǒng)也就是Windows的usernam。所以我們?cè)谂渲妹Q的時(shí)候最好前面加上jdbc.

5 Bean的作用域

5.1 singleton

默認(rèn)情況下,Spring的IoC容器創(chuàng)建的Bean對(duì)象是單例的。

@Testpublic void testBean(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");Customer customer1 = applicationContext.getBean("customer", Customer.class);System.out.println(customer1);Customer customer2 = applicationContext.getBean("customer", Customer.class);System.out.println(customer2);Customer customer3 = applicationContext.getBean("customer", Customer.class);System.out.println(customer3);}

如上我們調(diào)用三次getBean,返回的是同一個(gè)對(duì)象

那么這個(gè)對(duì)象在什么時(shí)候創(chuàng)建的呢,我們寫上無(wú)參構(gòu)造,把getBean方法都刪除,執(zhí)行程序,發(fā)現(xiàn)無(wú)參構(gòu)造執(zhí)行了,我們得知默認(rèn)情況下,Bean對(duì)象的創(chuàng)建是在初始化Spring上下文的時(shí)候就完成的。

5.2 prototype

如果想讓spring的bean對(duì)象以多例的形式存在,可以在bean標(biāo)簽中指定scope屬性的值為:prototype,這樣spring會(huì)在每一次執(zhí)行g(shù)etBean的時(shí)候都創(chuàng)建bean對(duì)象,調(diào)用幾次就創(chuàng)建幾次

我們?cè)賵?zhí)行上段代碼:?

這時(shí)如果不調(diào)用getBean方法,那么無(wú)參構(gòu)造就不會(huì)只執(zhí)行

5.3 其它scope

scope屬性的值不止兩個(gè),它一共包括8個(gè)選項(xiàng):

  • singleton:默認(rèn)的,單例。
  • prototype:原型。每調(diào)用一次getBean()方法則獲取一個(gè)新的Bean對(duì)象?;蛎看巫⑷氲臅r(shí)候都是新對(duì)象。
  • request:一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)Bean。僅限于在WEB應(yīng)用中使用。
  • session:一個(gè)會(huì)話對(duì)應(yīng)一個(gè)Bean。僅限于在WEB應(yīng)用中使用
  • global session:portlet應(yīng)用中專用的。如果在Servlet的WEB應(yīng)用中使用global session的話,和session一個(gè)效果。(portlet和servlet都是規(guī)范。servlet運(yùn)行在servlet容器中,例如Tomcat。portlet運(yùn)行在portlet容器中。)
  • application:一個(gè)應(yīng)用對(duì)應(yīng)一個(gè)Bean。僅限于在WEB應(yīng)用中使用。
  • websocket:一個(gè)websocket生命周期對(duì)應(yīng)一個(gè)Bean。僅限于在WEB應(yīng)用中使用。
  • 自定義scope:很少使用。

我們可以自己定義,但是沒(méi)必要,再見。

6 GoF工廠設(shè)計(jì)模式

設(shè)計(jì)模式:一種可以被重復(fù)利用的解決方案。GoF(Gang of Four),中文名——四人組。

GoF包括了23種設(shè)計(jì)模式。我們平常所說(shuō)的設(shè)計(jì)模式就是指這23種設(shè)計(jì)模式。

不過(guò)除了GoF23種設(shè)計(jì)模式之外,還有其它的設(shè)計(jì)模式,比如:JavaEE的設(shè)計(jì)模式(DAO模式、MVC模式等)。

GoF23種設(shè)計(jì)模式可分為三大類:

創(chuàng)建型(5個(gè)):解決對(duì)象創(chuàng)建問(wèn)題。

  • 單例模式
  • 原型模式
  • 建造者模式
  • 抽象工廠模式
  • 工廠方法模式

結(jié)構(gòu)型(7個(gè)):一些類或?qū)ο蠼M合在一起的經(jīng)典結(jié)構(gòu)。

  • 代理模式
  • 橋接模式
  • 外觀模式
  • 享元模式
  • 組合模式
  • 適配器模式
  • 裝飾模式

行為型(11個(gè)):解決類或?qū)ο笾g的交互問(wèn)題。

  • 策略模式
  • 解釋器模式
  • 中介者模式
  • 訪問(wèn)者模式
  • 狀態(tài)模式
  • 備忘錄模式
  • 命令模式
  • 迭代子模式
  • 觀察者模式
  • 責(zé)任鏈模式
  • 模板方法模式

工廠模式是解決對(duì)象創(chuàng)建問(wèn)題的,所以工廠模式屬于創(chuàng)建型設(shè)計(jì)模式。這里為什么學(xué)習(xí)工廠模式呢?這是因?yàn)镾pring框架底層使用了大量的工廠模式

6.1 工廠模式三種形態(tài)

工廠模式通常有三種形態(tài):

  • 第一種:簡(jiǎn)單工廠模式(Simple Factory):不屬于23種設(shè)計(jì)模式之一。簡(jiǎn)單工廠模式又叫做:靜態(tài) 工廠方法模式。簡(jiǎn)單工廠模式是工廠方法模式的一種特殊實(shí)現(xiàn)。
  • 第二種:工廠方法模式(Factory Method):是23種設(shè)計(jì)模式之一。
  • 第三種:抽象工廠模式(Abstract Factory):是23種設(shè)計(jì)模式之一。

6.2 簡(jiǎn)單工廠模式

簡(jiǎn)單工廠模式的角色包括三個(gè):

  • 抽象產(chǎn)品 角色
  • 具體產(chǎn)品 角色
  • 工廠類 角色

簡(jiǎn)單工廠模式的代碼如下:

抽象產(chǎn)品角色:

package com.itzw.factory;public abstract class Weapon {public abstract void attack(); }

具體產(chǎn)品角色:

package com.itzw.factory;public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("機(jī)槍正在發(fā)射...");} } package com.itzw.factory;public class Plane extends Weapon{@Overridepublic void attack() {System.out.println("飛機(jī)正在扔小男孩...");} } package com.itzw.factory;public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克正在開炮...");} }

工廠類角色:

package com.itzw.factory;public class WeaponFactory {public static Weapon get(String WeaponType){if ("GUN".equals(WeaponType)){return new Gun();}else if ("PLANE".equals(WeaponType)){return new Plane();}else if ("TANK".equals(WeaponType)){return new Tank();}else {throw new RuntimeException("不支持該武器");}} }

測(cè)試:

package com.itzw.factory;public class Test {public static void main(String[] args) {Weapon tank = WeaponFactory.get("TANK");tank.attack();Weapon plane = WeaponFactory.get("PLANE");plane.attack();Weapon gun = WeaponFactory.get("GUN");gun.attack();} }

這種模式就是簡(jiǎn)單工廠模式,它的優(yōu)點(diǎn):客戶端程序,也就是我們這里的 測(cè)試程序不需要關(guān)系對(duì)象的創(chuàng)建細(xì)節(jié),需要哪個(gè)對(duì)象只需要向工廠索要,初步實(shí)現(xiàn)了責(zé)任的分離??蛻舳酥回?fù)責(zé)消費(fèi),工廠只負(fù)責(zé)生產(chǎn)。但 它也有缺點(diǎn):工廠類中集中了所有產(chǎn)品的創(chuàng)造邏輯,一旦出問(wèn)題整個(gè)系統(tǒng)會(huì)癱瘓;還有就是比較明顯的,不符合OCP開閉原則,我們想擴(kuò)展系統(tǒng)時(shí)也就是比如需要擴(kuò)展一個(gè)新的武器需要修改工廠類。

6.3 工廠方法模式

工廠方法模式的角色包括:

  • 抽象工廠角色
  • 具體工廠角色
  • 抽象產(chǎn)品角色
  • 具體產(chǎn)品角色

抽象產(chǎn)品角色和具體產(chǎn)品角色和上面的簡(jiǎn)單工廠模式一樣:

package com.itzw.factory2;public abstract class Weapon {public abstract void attack(); } package com.itzw.factory2;public class Gun extends Weapon {@Overridepublic void attack() {System.out.println("機(jī)槍正在發(fā)射...");} } package com.itzw.factory2;public class Plane extends Weapon {@Overridepublic void attack() {System.out.println("飛機(jī)正在扔小男孩...");} }

抽象工廠角色:創(chuàng)建一個(gè)方法能讓它返回一個(gè)抽象產(chǎn)品角色

package com.itzw.factory2;public interface WeaponFactory {Weapon get(); }

具體工廠角色:

package com.itzw.factory2;public class GunFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Gun();} } package com.itzw.factory2;public class PlaneFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Plane();} }

測(cè)試:

package com.itzw.factory2;public class Test {public static void main(String[] args) {WeaponFactory gun = new GunFactory();gun.get().attack();WeaponFactory plane = new PlaneFactory();plane.get().attack();} }

這時(shí)我們?cè)傧爰尤胄碌奈淦骶筒恍枰薷拇a了,直接創(chuàng)建一個(gè)具體類繼承抽象類然后創(chuàng)建具體工廠角色繼承抽象工廠即可。

顯然這種模式符合OCP開閉原則,但是每次新增一個(gè)產(chǎn)品就需要?jiǎng)?chuàng)建兩個(gè)類,在一定程度上增加了系統(tǒng)的復(fù)雜度

6.4 抽象工廠模式(了解)

抽象工廠模式可以看做上面兩種模式的結(jié)合。

7 Bean的實(shí)例化方式

或者可以說(shuō)是bean的獲取方式

Spring為Bean提供了多種實(shí)例化方式,通常包括4種方式。(也就是說(shuō)在Spring中為Bean對(duì)象的創(chuàng)建準(zhǔn)備了多種方案,目的是:更加靈活)

  • 第一種:通過(guò)構(gòu)造方法實(shí)例化
  • 第二種:通過(guò)簡(jiǎn)單工廠模式實(shí)例化
  • 第三種:通過(guò)factory-bean實(shí)例化
  • 第四種:通過(guò)FactoryBean接口實(shí)例化

7.1 通過(guò)構(gòu)造方法實(shí)例化

之前我們學(xué)習(xí)的就是通過(guò)構(gòu)造方法實(shí)例化:

package com.itzw.constructor;public class User {public User(){System.out.println("User的無(wú)參構(gòu)造執(zhí)行了");} }

spring配置文件:

<bean id="user" class="com.itzw.constructor.User"/>

測(cè)試:

@Testpublic void testConstructor(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Object user = applicationContext.getBean("user", User.class);System.out.println(user);}

7.2 通過(guò)簡(jiǎn)單工廠模式實(shí)例化

bean:

package com.itzw.bean;public class Vip {public Vip(){System.out.println("vip的無(wú)參構(gòu)造執(zhí)行了");} }

編寫簡(jiǎn)單工廠模式中的工廠類:這里的方法是靜態(tài)方法

package com.itzw.bean;public class VipFactory {public static Vip get(){return new Vip();} }

spring.xml:

我們需要在這指定調(diào)用哪個(gè)類的哪個(gè)方法獲取Bean。factory-method屬性指定的是工廠類當(dāng)中的靜態(tài)方法,也就是告訴spring框架調(diào)用這個(gè)方法可以獲取bean

<!--通過(guò)簡(jiǎn)單工廠模式實(shí)例化--><bean class="com.itzw.bean.VipFactory" id="vip" factory-method="get"/>

7.3 通過(guò)factory-bean實(shí)例化

這種方式本質(zhì)上是:通過(guò)工廠方法模式進(jìn)行實(shí)例化。

和上個(gè)方法的區(qū)別就是spring配置文件的配置不同,把一個(gè)bean標(biāo)簽分解成兩個(gè),并且具體工廠類的方法是實(shí)例方法如下:

package com.itzw.bean;public class Order {public Order(){System.out.println("Order的無(wú)參構(gòu)造執(zhí)行了");} }

注意這里的方法是實(shí)例方法

package com.itzw.bean;public class OrderFactory {public Order get(){return new Order();} }

spring:factory-bean告訴框架調(diào)用哪個(gè)對(duì)象,factory-method告訴框架調(diào)用哪個(gè)方法。

<!--通過(guò)工廠方法模式--><bean class="com.itzw.bean.OrderFactory" id="orderFactory"/><bean factory-bean="orderFactory" factory-method="get" id="order" />

7.4 通過(guò)FactoryBean接口實(shí)例化

以上三種方法,需要我們自定義factory-bean或者factory-method。在我們編寫類實(shí)現(xiàn)FactoryBean接口后這倆屬性就不需要指定了,factory-bean會(huì)自動(dòng)指向?qū)崿F(xiàn)FactoryBean接口的類,factory-method會(huì)自動(dòng)指向getObject方法

package com.itzw.bean;public class Animal {public Animal(){System.out.println("Animal構(gòu)造方法執(zhí)行了");} }

具體工廠類實(shí)現(xiàn)FactoryBean接口

package com.itzw.bean;import org.springframework.beans.factory.FactoryBean;public class AnimalFactory implements FactoryBean<Animal> {@Overridepublic Animal getObject() throws Exception {return new Animal();}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();} } <!--通過(guò)FactoryBean接口--><bean class="com.itzw.bean.Animal" id="animal"/>

7.5 BeanFactory和FactoryBean的區(qū)別

7.5.1 BeanFactory

Spring IoC容器的頂級(jí)對(duì)象,BeanFactory被翻譯為“Bean工廠”,在Spring的IoC容器中,“Bean工廠”負(fù)責(zé)創(chuàng)建Bean對(duì)象。

BeanFactory是工廠。

7.5.2 FactoryBean

FactoryBean:它是一個(gè)Bean,是一個(gè)能夠輔助Spring實(shí)例化其它Bean對(duì)象的一個(gè)Bean。

在Spring中,Bean可以分為兩類:

  • 第一類:普通Bean
  • 第二類:工廠Bean(記住:工廠Bean也是一種Bean,只不過(guò)這種Bean比較特殊,它可以輔助Spring實(shí)例化其它Bean對(duì)象。)

7.6 注入自定義Date

我們?cè)谇懊婢椭v到過(guò)Date類型是簡(jiǎn)單類型可以直接使用value屬性賦值,但是對(duì)格式要求非常嚴(yán)格,只能是這樣類型的:Mon Oct 10 14:30:26 CST 2022,而這種類型不符合我們常見的格式。

package com.itzw.bean;import java.util.Date;public class Student {private Date date;public void setDate(Date date) {this.date = date;}@Overridepublic String toString() {return "Student{" +"date=" + date +'}';} } <!--Date類型的注入--><bean class="com.itzw.bean.Student" id="student"><property name="date" value="Mon Oct 10 14:30:26 CST 2022"/></bean>

以上就是我們對(duì)Date類型當(dāng)做簡(jiǎn)單類型的注入。

我們可以把Date當(dāng)做非簡(jiǎn)單類型注入:

還是那個(gè)Student類,我們創(chuàng)建Date工廠實(shí)現(xiàn)FactoryBean,并且定義屬性和構(gòu)造方法接收spring配置文件傳來(lái)的日期,我們使用SimpleDateFormat定義日期格式接收傳來(lái)的日期(比如2020-8-8),然后會(huì)返回一個(gè)日期

package com.itzw.bean;import org.springframework.beans.SimpleTypeConverter; import org.springframework.beans.factory.FactoryBean;import java.text.SimpleDateFormat; import java.util.Date;public class DateFactoryBean implements FactoryBean<Date> {//定義屬性接收日期private String date;//通過(guò)構(gòu)造方法給日期賦值public DateFactoryBean(String date) {this.date = date;}@Overridepublic Date getObject() throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date date = sdf.parse(this.date);return date;}@Overridepublic Class<?> getObjectType() {return null;} }

傳給date工廠一個(gè)日期,會(huì)返回一個(gè)Date默認(rèn)格式的日期,然后我們?cè)偻ㄟ^(guò)Student的Bean將這個(gè)日期傳給Student。

<!--Date類型的注入(非簡(jiǎn)單類型)--><bean id="dateFactoryBean" class="com.itzw.bean.DateFactoryBean"><constructor-arg name="date" value="2000-9-25"/></bean><bean class="com.itzw.bean.Student" id="student2"><property name="date" ref="dateFactoryBean"/></bean>

8 Bean的聲明周期

8.1 什么是Bean的生命周期

  • Spring其實(shí)就是一個(gè)管理Bean對(duì)象的工廠。它負(fù)責(zé)對(duì)象的創(chuàng)建,對(duì)象的銷毀等。
  • 所謂的生命周期就是:對(duì)象從創(chuàng)建開始到最終銷毀的整個(gè)過(guò)程。
  • 什么時(shí)候創(chuàng)建Bean對(duì)象?
  • 創(chuàng)建Bean對(duì)象的前后會(huì)調(diào)用什么方法?
  • Bean對(duì)象什么時(shí)候銷毀?
  • Bean對(duì)象的銷毀前后調(diào)用什么方法?

8.2 為什么要知道Bean的生命周期

  • 其實(shí)生命周期的本質(zhì)是:在哪個(gè)時(shí)間節(jié)點(diǎn)上調(diào)用了哪個(gè)類的哪個(gè)方法。
  • 我們需要充分的了解在這個(gè)生命線上,都有哪些特殊的時(shí)間節(jié)點(diǎn)。
  • 只有我們知道了特殊的時(shí)間節(jié)點(diǎn)都在哪,到時(shí)我們才可以確定代碼寫到哪。
  • 我們可能需要在某個(gè)特殊的時(shí)間點(diǎn)上執(zhí)行一段特定的代碼,這段代碼就可以放到這個(gè)節(jié)點(diǎn)上。當(dāng)生命線走到這里的時(shí)候,自然會(huì)被調(diào)用。

8.3 Bean的聲明周期之五步

Bean生命周期可以粗略的劃分為五大步:

  • 第一步:實(shí)例化Bean
  • 第二步:Bean屬性賦值
  • 第三步:初始化Bean
  • 第四步:使用Bean
  • 第五步:銷毀Bean

這五步的位置如下:

注意:我們需要自己寫初始化和銷毀方法,并且最后我們要手動(dòng)關(guān)閉銷毀方法。我們還要在spring配置文件中指定初始化方法和銷毀方法。

package com.itzw.spring6.lifecycle;public class User {private String name;public User(){System.out.println("1.實(shí)例化bean");}public void setName(String name) {this.name = name;System.out.println("2.給bean屬性賦值");}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}public void initBean(){System.out.println("3.初始化bean");}public void destroyBean(){System.out.println("4.銷毀bean");} } <!--我們自己創(chuàng)建的初始化bean和銷毀bean方法都需要在這里指定,因?yàn)槭俏覀冏约簞?chuàng)建的不可能自動(dòng)識(shí)別--><bean id="user" class="com.itzw.spring6.lifecycle.User"init-method="initBean" destroy-method="destroyBean"><property name="name" value="張麻子"/></bean> @Testpublic void testLifeCycle(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User user = applicationContext.getBean("user", User.class);//System.out.println(user);System.out.println("4.使用bean");//我們需要手動(dòng)關(guān)閉spring容器才能執(zhí)行銷毀方法,我們還需要將applicationContext強(qiáng)轉(zhuǎn)為ClassPathXmlApplicationContextClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;context.close();}

8.4 Bean生命周期之7步

在以上的5步的基礎(chǔ)上,在第3步初始化Bean前后可以各加一步,可以加入我們想加入的代碼,這一共就是七步了,可以加入“Bean后處理器”。

編寫一個(gè)類實(shí)現(xiàn)BeanPostProcessor類,并且重寫before和after方法:

package com.itzw.spring6.lifecycle;import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor;public class LogBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("Bean后處理器的before方法執(zhí)行,即將開始初始化");return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("Bean后處理器的before方法執(zhí)行,已經(jīng)完成初始化");return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);} }

我們需要在spring配置文件中配置bean后處理器,相當(dāng)于引入這個(gè)類。

<!--配置Bean后處理器。這個(gè)后處理器將作用于當(dāng)前配置文件中所有的bean。--><bean class="com.itzw.spring6.lifecycle.LogBeanPostProcessor"/>

8.5 Bean生命周期之10步

在上面七步的基礎(chǔ)上,在Bean后處理器before執(zhí)行之前檢查bean是否實(shí)現(xiàn)Aware的相關(guān)接口,并設(shè)置相關(guān)依賴,在Bean后處理器before執(zhí)行之后檢查bean是否實(shí)現(xiàn)了InitialzingBean接口,并調(diào)用接口方法,在銷毀bean之前檢查bean是否實(shí)現(xiàn)了DisposableBean接口,并調(diào)用接口方法。

以上三個(gè)檢查接口并執(zhí)行相關(guān)方法或依賴一共是三步,加上前面的七步一共是十步。

那這些接口是什么意思呢?

Aware相關(guān)的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

當(dāng)Bean實(shí)現(xiàn)了BeanNameAware,Spring會(huì)將Bean的名字傳遞給Bean

當(dāng)Bean實(shí)現(xiàn)了BeanClassLoaderAware,Spring會(huì)加載該Bean的類加載器傳遞給bean

當(dāng)Bean實(shí)現(xiàn)了BeanFactoryAware,Spring會(huì)將Bean工廠對(duì)象傳遞給bean?

我們實(shí)現(xiàn)這些接口感受一下:

package com.itzw.spring6.lifecycle;import org.springframework.beans.BeansException; import org.springframework.beans.factory.*;public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean,DisposableBean {private String name;public User(){System.out.println("1.實(shí)例化bean");}public void setName(String name) {this.name = name;System.out.println("2.給bean屬性賦值");}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}public void initBean(){System.out.println("4.初始化bean");}public void destroyBean(){System.out.println("7.銷毀bean");}@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("這個(gè)bean的類加載器是:"+classLoader);}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("這個(gè)bean的工廠對(duì)象是:"+beanFactory);}@Overridepublic void setBeanName(String name) {System.out.println("這個(gè)bean的名字是:"+name);}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean接口在后處理器的before方法執(zhí)行之后執(zhí)行了");}@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean接口在銷毀bean前執(zhí)行了");} }

對(duì)于生命周期我們掌握七種就可以

8.6 Bean的作用域不同,管理方式不同

Spring根據(jù)bean的作用域來(lái)選擇管理方式

  • 對(duì)于singleton作用域的bean,Spring能夠精確的知道該bean何時(shí)被創(chuàng)建,以及何時(shí)被銷毀
  • 而對(duì)于prototype作用域的bean,spring只負(fù)責(zé)創(chuàng)建

我們把之前User類的spring.xml文件中的片配置scope設(shè)置為prototype:

只執(zhí)行了前八步

9 Bean的循環(huán)依賴問(wèn)題

9.1 什么是Bean的循環(huán)依賴

A對(duì)象有B屬性,B對(duì)象有A屬性。比如Husband對(duì)象有Wife屬性,Wife對(duì)象有Husband屬性,如下:

package com.itzw.spring6.bean;public class Husband {private String name;private Wife wife; } package com.itzw.spring6.bean;public class Wife {private String name;private Husband husband; }

9.2 singleton下的set注入產(chǎn)生的循環(huán)依賴

package com.itzw.spring6.bean;public class Husband {private String name;private Wife wife;public String getName() {return name;}public void setName(String name) {this.name = name;}public void setWife(Wife wife) {this.wife = wife;}@Overridepublic String toString() {return "Husband{" +"name='" + name + '\'' +", wife=" + wife.getName() +'}';} } package com.itzw.spring6.bean;public class Wife {private String name;private Husband husband;public String getName() {return name;}public void setName(String name) {this.name = name;}public void setHusband(Husband husband) {this.husband = husband;}@Overridepublic String toString() {return "Wife{" +"name='" + name + '\'' +", husband=" + husband.getName() +'}';} }

注意這里的toString方法里面不能直接輸出husband和wife對(duì)象,因?yàn)檫@樣就遞歸了,我們指定輸出對(duì)應(yīng)的get方法即可

<bean class="com.itzw.spring6.bean.Husband" id="husband" scope="singleton"><property name="name" value="張麻子"/><property name="wife" ref="wife"/></bean><bean class="com.itzw.spring6.bean.Wife" id="wife" scope="singleton"><property name="name" value="馬邦德"/><property name="husband" ref="husband"/></bean> @Testpublic void testDC(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Husband husband = applicationContext.getBean("husband", Husband.class);System.out.println(husband);Wife wife = applicationContext.getBean("wife", Wife.class);System.out.println(wife);}

通過(guò)測(cè)試得知:在singleton + set注入的情況下,循環(huán)依賴是沒(méi)有問(wèn)題的。Spring可以解決這個(gè)問(wèn)題。

我們簡(jiǎn)單分析一下原理:因?yàn)槭褂玫氖莝ingleton是單例模式,對(duì)象只會(huì)實(shí)例化一次,所以在spring容器加載的時(shí)候?qū)嵗痓ean,只要進(jìn)行實(shí)例化后就會(huì)立刻“曝光”【不等屬性值賦值就曝光了】。比如在給Husband對(duì)象賦值的時(shí)候需要得到WIfe對(duì)象才能完成賦值,而這時(shí)Wife對(duì)象已經(jīng)實(shí)例化已經(jīng)曝光可以得到。同樣的Wife對(duì)象在賦值的時(shí)候需要Husband對(duì)象,此時(shí)Husband對(duì)象也已經(jīng)實(shí)例化結(jié)束已經(jīng)曝光,所以不會(huì)出現(xiàn)問(wèn)題。

9.3 prototype下的set注入產(chǎn)生的循環(huán)依賴

scope改成prototype

這樣會(huì)出錯(cuò):

提示我們:請(qǐng)求的 bean 目前正在創(chuàng)建中:是否有無(wú)法解析的循環(huán)引用?

那為什么會(huì)出錯(cuò)呢?因?yàn)槭褂玫氖莗rototype。在我們給Husband賦值的時(shí)候需要注入WifeBean,這就需要new一個(gè)新的Wife對(duì)象給Husband,而new出的Wife對(duì)象需要Husband對(duì)象才行,這時(shí)又會(huì)new一個(gè)新的Husband對(duì)象...會(huì)成死循環(huán)。

但如果有一個(gè)Bean的scope是singleton就不會(huì)出錯(cuò)了。比如WIfe是singleton

當(dāng)我們給Husband賦值的時(shí)候,需要Wife對(duì)象,因?yàn)閃ife對(duì)象是單例的只有一個(gè)固定的,會(huì)曝光,Husband對(duì)象就能得到了。當(dāng)我們給Wife對(duì)象賦值的時(shí)候,需要Husband,Husband會(huì)new一個(gè)新的對(duì)象,此時(shí)Husband需要Wife對(duì)象,因?yàn)閃Ife對(duì)象是單例的,直接就可以得到了。

9.4 singleton下的構(gòu)造注入產(chǎn)生的循環(huán)依賴

package com.itzw.spring6.bean2;public class Husband {private String name;private Wife wife;public String getName() {return name;}public Husband(String name, Wife wife) {this.name = name;this.wife = wife;}@Overridepublic String toString() {return "Husband{" +"name='" + name + '\'' +", wife=" + wife.getName() +'}';} } package com.itzw.spring6.bean2;public class Wife {private String name;private Husband husband;public String getName() {return name;}public Wife(String name, Husband husband) {this.name = name;this.husband = husband;}@Overridepublic String toString() {return "Wife{" +"name='" + name + '\'' +", husband=" + husband.getName() +'}';} } <bean id="husband" class="com.itzw.spring6.bean2.Husband" scope="singleton"><constructor-arg name="name" value="張麻子"/><constructor-arg ref="wife"/></bean><bean id="wife" class="com.itzw.spring6.bean2.Wife" scope="singleton"><constructor-arg name="name" value="馬邦德"/><constructor-arg name="husband" ref="husband"/></bean>

測(cè)試結(jié)果是失敗的,錯(cuò)誤和上面的錯(cuò)一樣,為什么呢?

因?yàn)槭褂脴?gòu)造注入,這要求我們?cè)趯?shí)例化bean的時(shí)候就要給屬性值賦值,但是經(jīng)過(guò)上面那些分析我們就應(yīng)該已經(jīng)明白了,我們是做不到實(shí)例化就立刻給屬性賦值的,這會(huì)造成死循環(huán)。

小小總結(jié)一下:經(jīng)過(guò)上面測(cè)試我們發(fā)現(xiàn)只有在使用set方法注入并且scope的值為singleton的時(shí)候才能避免循環(huán)依賴。

根本原因在于,這種方式可以做到“實(shí)例化Bean”和“給Bean屬性賦值”這兩個(gè)動(dòng)作分開完成。實(shí)例化bean的時(shí)候調(diào)用無(wú)參構(gòu)造來(lái)完成,此時(shí)可以先不給屬性賦值,可以提前將該bean“曝光”給外界。

也就是說(shuō),Bean都是單例的,我們可以先把所有的單例bean實(shí)例化出來(lái),放到一個(gè)集合當(dāng)中(我們可以稱之為緩存)所有的bean都實(shí)例化完成之后,以后我們?cè)俾恼{(diào)用set方法給屬性賦值,這樣就解決了循環(huán)依賴的問(wèn)題。

10 回顧反射機(jī)制

10.1 分析方法四要素

我們隨便創(chuàng)建一個(gè)類:

package com.itzw.reflect;public class Student {private String name;private int age;public void doSome(){System.out.println("doSome無(wú)參方法執(zhí)行");}public String doSome(String name){System.out.println("doSome返回姓名的方法執(zhí)行");return name;} }

我們調(diào)用這個(gè)類的方法:

package com.itzw.reflect;public class Test {public static void main(String[] args) {Student student = new Student();student.doSome();String doSome = student.doSome("王德發(fā)");System.out.println(doSome);} }

我們發(fā)現(xiàn)調(diào)用一個(gè)類的方法需要四要素:類的對(duì)象;方法名;方法參數(shù);返回值

10.2 使用反射機(jī)制調(diào)用方法

還是那個(gè)類,不過(guò)我們使用反射機(jī)制的方式調(diào)用方法

package com.itzw.reflect;import java.lang.reflect.Method;public class Test2 {public static void main(String[] args) throws Exception {//獲取類Class<?> clazz = Class.forName("com.itzw.reflect.Student");//獲取方法Method doSome = clazz.getDeclaredMethod("doSome", String.class);//獲取類的對(duì)象Object obj = clazz.newInstance();//調(diào)用方法Object retValue = doSome.invoke(obj, "張麻子");//輸出返回值System.out.println(retValue);} }

10.3 假設(shè)知道屬性名

package com.itzw.reflect;public class User {private String name;private int age;public User(){}public User(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';} }

假設(shè)有如上的一個(gè)類,你知道的信息是:

  • 類名是:com.itzw.reflect.User
  • 該類中有String類型的name屬性和int類型的age屬性
  • 另外你知道該類的設(shè)計(jì)符合javabean規(guī)范

知道以上信息如何給屬性賦值呢?

我們這里給age屬性賦值:

package com.itzw.reflect;import java.lang.reflect.Method;public class Test3 {public static void main(String[] args) throws Exception{String className = "com.itzw.reflect.User";String propertyName = "age";String setMethodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);//獲取類Class<?> clazz = Class.forName(className);//獲取方法Method setMethod = clazz.getDeclaredMethod(setMethodName,int.class);//獲取對(duì)象Object obj = clazz.newInstance();//調(diào)用方法setMethod.invoke(obj,12);//輸出類System.out.println(obj);} }

之所以回顧反射機(jī)制是為了下面手寫spring框架

總結(jié)

以上是生活随笔為你收集整理的SSM框架-Spring(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

国产在线精品一区二区 | 黄色av成人在线观看 | 国产成人在线免费观看 | 在线观看免费成人av | 黄色软件在线观看视频 | 一区二区三区在线不卡 | 成人免费观看网址 | 国产午夜精品一区二区三区欧美 | 国产在线高清精品 | 麻豆久久| 久久综合九色综合欧美就去吻 | 国产精品女主播一区二区三区 | 国产又粗又猛又色又黄视频 | 亚洲成年人在线播放 | 久久国产精品久久w女人spa | 天天爽天天搞 | 日韩伦理一区二区三区av在线 | 美女黄频在线观看 | 成人黄色大片在线观看 | 91久久精品一区二区三区 | 亚洲精品国产精品久久99 | 国产精品孕妇 | 夜夜天天干 | 成人免费视频播放 | 天堂va欧美va亚洲va老司机 | 园产精品久久久久久久7电影 | 国产福利不卡视频 | 91精品久久久久久综合乱菊 | 超碰电影在线观看 | 欧美久久久久 | 久久免费av电影 | 中文字幕在线播放日韩 | 在线看成人av | 探花视频免费在线观看 | 超碰在线最新网址 | 玖玖在线免费视频 | 国产亚洲精品久久久久秋 | 久久久免费视频播放 | 久久伊人免费视频 | 精品成人网 | 亚洲午夜久久久久久久久电影网 | 91免费视频网站在线观看 | 免费网站在线 | 国产涩涩在线观看 | 国产在线观看网站 | 午夜av在线播放 | 天天se天天cao天天干 | 亚洲精品久久久蜜臀下载官网 | 久草在线视频精品 | 97在线观看视频免费 | 99久热 | 天天色天天色天天色 | 91av视频导航 | 欧美一区中文字幕 | 伊人狠狠色 | 一本一本久久aa综合精品 | 日韩二区在线播放 | 九色免费视频 | 日本精品久久久久中文字幕 | 中文字幕精品视频 | 色偷偷97 | 日韩激情影院 | 久草网视频在线观看 | 久久人人爽人人 | 91精品国产高清自在线观看 | 99综合影院在线 | 五月婷婷丁香在线观看 | 国产传媒一区在线 | 亚洲无人区小视频 | 中文字幕日韩无 | 中文字幕婷婷 | 亚洲视频在线观看免费 | 色av色av色av | 色噜噜在线观看 | 国产一级片免费播放 | 日韩久久一区二区 | 国产一二三在线视频 | 国模视频一区二区三区 | 激情xxxx | 中文字幕高清av | 狠狠色伊人亚洲综合网站色 | 国产精品久久久久久超碰 | 五月天开心 | 国内99视频 | 国产免费观看视频 | 在线成人免费电影 | 久久99精品久久久久久 | 蜜臀久久99静品久久久久久 | 在线不卡的av| 亚洲激情视频在线 | 精品成人网 | 成人在线视频网 | 欧美xxxxx在线视频 | 日本性高潮视频 | 久草免费资源 | 婷婷激情网站 | 日韩午夜三级 | 国产xx在线 | 成人免费ⅴa | 成人精品一区二区三区中文字幕 | 色的网站在线观看 | 99热在线观看免费 | 999久久久久久久久6666 | 国产很黄很色的视频 | 亚洲精品乱码久久久久久蜜桃91 | 天天爱天天射天天干天天 | 爱射综合 | a视频在线 | 欧美坐爱视频 | 99久久久国产精品免费99 | 亚洲欧美成人综合 | 黄色一区三区 | 免费在线观看不卡av | 午夜av大片 | 国产精品九色 | 99在线国产 | 国产亚洲精品精品精品 | 91麻豆精品国产午夜天堂 | 国产精品欧美久久久久三级 | 色中色亚洲 | 欧美日韩国产免费视频 | 69成人在线| 免费男女羞羞的视频网站中文字幕 | 夜色资源站国产www在线视频 | 久色 网 | 欧美韩国日本在线观看 | 亚洲免费公开视频 | 天天色天天操综合 | 国产精品视频最多的网站 | 欧美日韩国产在线精品 | 日韩欧美一级二级 | 九色精品在线 | 欧美一级看片 | 国产成人精品久久亚洲高清不卡 | 久久视频在线免费观看 | 午夜精品一区二区三区在线观看 | 91麻豆精品久久久久久 | 欧美资源 | 久久99久久99精品免观看粉嫩 | 日韩肉感妇bbwbbwbbw | 午夜精品久久久久久久久久久久久久 | 日韩av一区二区三区 | 欧美 激情 国产 91 在线 | 丰满少妇在线观看网站 | 免费看国产精品 | 免费成人在线视频网站 | 天天干天天干天天干天天干天天干天天干 | 六月丁香六月婷婷 | 中文字幕久久精品一区 | 国产手机在线观看视频 | 国产一区自拍视频 | 天天综合五月天 | 日韩丝袜在线观看 | 国产成免费视频 | www.91国产 | www.夜夜干.com| 黄色a视频免费 | 久久免费电影网 | 欧美日韩三级在线观看 | 国产麻豆精品久久一二三 | 热re99久久精品国产66热 | 天天摸日日摸人人看 | 国产精品久久网 | 午夜视频在线观看一区二区三区 | 久久综合影院 | 精品亚洲一区二区三区 | 国产精品热视频 | 欧美久久久久久久久中文字幕 | 四虎伊人 | 午夜91视频 | 亚洲精品国产成人 | 久久精品之 | 久草在线久 | 免费观看成年人视频 | 国产福利在线不卡 | 菠萝菠萝在线精品视频 | 精品久久久久久亚洲 | 国产精品自在线 | 国产精品美女久久久久久久久 | 国模吧一区 | 国产福利91精品张津瑜 | 日日夜夜人人天天 | 国内精品久久久久久久久久 | 久久三级毛片 | 国产精品午夜久久久久久99热 | 在线视频亚洲 | 国产一区二区三区四区在线 | 久久婷婷网| 国产精品激情偷乱一区二区∴ | 国产精品免费不 | 午夜精品一区二区三区四区 | japanese黑人亚洲人4k | 最新婷婷色 | 亚洲美女在线国产 | 婷婷激情五月 | 青春草免费在线视频 | 91在线观看黄| 久久av影院 | 国产手机视频精品 | 黄色aa久久 | 伊人天天狠天天添日日拍 | 亚洲在线视频播放 | 久草精品视频在线播放 | 99精品欧美一区二区三区黑人哦 | 成人av资源网站 | 一二三区视频在线 | 日韩和的一区二在线 | 久久精品国产精品亚洲 | 四虎国产免费 | 中文字幕欧美三区 | 色视频国产直接看 | 日韩中文久久 | av成人在线播放 | 久久久久久久久久久网 | 九草视频在线 | 九九免费观看全部免费视频 | 午夜狠狠干 | 亚洲欧美婷婷六月色综合 | 成人在线视频免费观看 | 成年人在线看片 | 午夜精品久久久久久 | 亚洲色综合 | 国产黄色免费观看 | 久草综合视频 | 中文在线字幕观看电影 | 超碰人人乐| 亚洲影音先锋 | 国产一区在线免费观看 | 一区二区三区免费在线观看视频 | 五月婷婷视频在线 | 亚洲理论在线 | 男女精品久久 | 免费在线观看av网址 | 国产亚洲视频中文字幕视频 | 色婷婷激情综合 | 午夜神马福利 | av在线免费观看黄 | 久草在线免费新视频 | 国产黄a三级三级 | 91精品免费看 | 精品伊人久久久 | 精品国产一区二区三区噜噜噜 | 亚洲,国产成人av | 久久尤物电影视频在线观看 | 超碰免费97 | 精品视频9999 | 国产一级在线观看视频 | 91xav| 欧美综合国产 | 免费看的毛片 | www.福利 | 中文字幕在线色 | www.久久久精品| 国产免费国产 | 成人国产精品久久久春色 | 国产色拍拍拍拍在线精品 | 亚洲一区二区三区在线看 | 91传媒在线播放 | 国产麻豆精品在线观看 | 国产馆在线播放 | 午夜色性片 | 激情影音| 国产一区二区综合 | 91男人影院 | 国产精品2020| 黄网站免费大全入口 | 免费日韩精品 | 久久久久久久久久亚洲精品 | 黄色动态图xx | 91av蜜桃| 色在线视频 | 欧洲精品一区二区 | 成人黄性视频 | 亚洲91中文字幕无线码三区 | 午夜视频导航 | 国产精品色视频 | 97在线观看免费高清完整版在线观看 | 久久久久成人精品 | 97视频免费观看 | 伊人激情综合 | 一级特黄aaa大片在线观看 | 少妇资源站 | 在线观看日本韩国电影 | 免费久久99精品国产 | 亚洲黄色成人网 | 亚洲一区二区三区在线看 | 在线观看福利网站 | 久久久久久免费 | 黄色一级免费网站 | 亚洲免费在线播放视频 | 欧美一区三区四区 | 中文字幕在线高清 | 天天干天天操人体 | 一级黄色片在线 | 在线观看中文 | 又黄又刺激视频 | 午夜精品999 | 欧美成人黄色片 | 精品一区 在线 | 久久综合九色综合97_ 久久久 | 免费日韩一区 | 久久8精品 | 精品专区一区二区 | 久久歪歪 | 韩日精品中文字幕 | 一区二区视频在线免费观看 | 成人免费网站视频 | 久久人人爽爽人人爽人人片av | 婷婷色综合色 | 国产小视频免费在线观看 | 亚洲伊人网在线观看 | 又紧又大又爽精品一区二区 | 久久黄色免费观看 | 国产精品福利小视频 | 日本九九视频 | 午夜精品福利一区二区三区蜜桃 | 色av网站| 亚洲精品一区二区三区新线路 | 婷婷色av| 国产精品一区二区视频 | 天堂av在线网站 | 色偷偷人人澡久久超碰69 | 亚洲精品一区二区三区新线路 | 亚洲福利精品 | 91久久丝袜国产露脸动漫 | h动漫中文字幕 | 亚洲一二三久久 | 久久久久久国产精品 | 免费又黄又爽 | 超碰久热 | 国产在线传媒 | 在线成人看片 | 亚洲精品乱码久久 | 男女精品久久 | 色综合久久久久综合体 | 亚洲精品一区二区三区新线路 | 成人蜜桃 | 国产高清在线免费视频 | 日韩精品一区二区三区三炮视频 | 日日夜夜操操 | 97国产视频| av黄色在线播放 | 欧美日韩国产一区 | 天天操天天玩 | 亚洲成人欧美 | 亚洲做受高潮欧美裸体 | 综合久久精品 | 激情综合久久 | 欧美成人手机版 | 在线观看91精品国产网站 | 99久久精品无码一区二区毛片 | 欧美日韩亚洲第一页 | 免费av黄色| 国产精品久久综合 | 91资源在线 | 99久久国产免费免费 | 国产亚洲成av人片在线观看桃 | 天天爱av导航 | 免费观看成人网 | 91原创在线观看 | 亚洲热视频 | 亚洲激情国产精品 | 四虎国产永久在线精品 | 精品久久久久久久久中文字幕 | 亚洲精品黄 | 精品超碰| 欧美日韩高清一区 | 日韩综合在线观看 | 国产免费黄视频在线观看 | 麻豆视频在线免费观看 | 美女天天操 | 久久99婷婷 | av电影免费在线看 | 午夜在线免费视频 | 久久久久久久久久久久久久电影 | 国产欧美精品xxxx另类 | 成人免费ⅴa| 国产精品一区一区三区 | 欧美精品久久99 | 国产在线一区二区 | 99精品视频精品精品视频 | 中文字幕在线播放一区 | 亚洲自拍偷拍色图 | 日韩中文字幕免费电影 | 伊人色**天天综合婷婷 | 成人黄色大片在线免费观看 | 狠狠躁夜夜av | 日日干综合 | 婷婷综合激情 | 成人午夜黄色影院 | 国产亚洲成人网 | 91国内在线 | 性色xxxxhd | 不卡国产在线 | 日韩久久久久久久 | 久久老司机精品视频 | 有码中文字幕 | 一区二区精品在线 | 99久久精品免费看国产 | 亚洲第五色综合网 | 天天干天天搞天天射 | 国产手机在线播放 | 色在线视频网 | 91成人看片 | 看片的网址 | 国产成人精品综合久久久久99 | 亚洲无吗av | 日本特黄特色aaa大片免费 | 色噜噜日韩精品一区二区三区视频 | 一级欧美黄 | 欧美日韩国产一区二区三区在线观看 | 欧美综合色 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 国产精品第一页在线 | 色资源网在线观看 | 国产精品免费视频久久久 | 精品国内自产拍在线观看视频 | 9999在线 | www.99在线观看 | 亚洲成a人片在线www | 亚洲精品久久久久久久蜜桃 | 亚洲精品免费在线观看 | 97免费| 久久精品视频观看 | 中文字幕日韩免费视频 | 成人av av在线 | 天天射天天射 | 日韩av快播电影网 | 992tv在线观看 | 激情久久伊人 | 国产这里只有精品 | 五月天婷婷免费视频 | 蜜桃传媒一区二区 | 亚洲精品视频大全 | 国产美女网站视频 | av成人亚洲 | 日韩有码中文字幕在线 | 欧美激情视频免费看 | 成人全视频免费观看在线看 | 成人a大片 | 在线播放国产精品 | 天堂av免费 | 久久久久久网址 | 亚洲1级片 | 亚洲国产精品视频在线观看 | 91成人在线观看高潮 | 日本乱码在线 | 国产精品18久久久 | 国产精品久久久久国产精品日日 | 欧美成人精品欧美一级乱黄 | 国产一区二区在线免费观看 | 99亚洲国产 | av免费观看网站 | 久久精品播放 | 亚洲免费专区 | 国产福利中文字幕 | 人人干在线| 国产精品中文字幕在线播放 | 色欧美88888久久久久久影院 | 18网站在线观看 | 国产在线观看91 | 免费日韩一级片 | 狠狠操夜夜| 日韩精品在线一区 | 欧美极度另类 | 五月天六月丁香 | 中文字幕五区 | 91视频午夜| 久久乐九色婷婷综合色狠狠182 | 韩日成人av| 国产又黄又硬又爽 | 日韩一区二区三免费高清在线观看 | 久久久久久久久影视 | 日本黄色免费播放 | 日韩精品视 | 亚洲精品国偷自产在线99热 | 午夜av影院 | 91成人精品一区在线播放69 | 亚洲一区欧美精品 | 深爱激情av | 日韩在线国产精品 | 日日夜操 | 成人免费在线播放视频 | 成人午夜性影院 | 天天艹天天爽 | 国产va饥渴难耐女保洁员在线观看 | 中国成人一区 | 久久最新网址 | 美女国产精品 | 亚洲精品在线电影 | 亚洲人人精品 | 日操操 | 夜夜爽88888免费视频4848 | 日韩中文在线视频 | 日韩高清在线一区二区三区 | 97人人模人人爽人人少妇 | 人人插超碰 | 精品免费观看 | 波多野结衣精品在线 | 超碰.com | 国产精品久久久av | 久操中文字幕在线观看 | 美女视频黄免费网站 | 天天射天天拍 | 激情在线免费视频 | 国产免费久久av | 国产精品 中文字幕 亚洲 欧美 | 99精品视频在线观看 | 久久久这里有精品 | 成人黄色片免费看 | h视频日本| 天天射天天舔天天干 | 免费三级骚 | 精品uu | 欧美精品久久久久 | 久久综合九色欧美综合狠狠 | 国产区免费在线 | 五月天久久 | 免费国产在线视频 | 国产无遮挡猛进猛出免费软件 | 一区二区三区在线影院 | 狠狠狠狠狠狠干 | 日韩电影中文字幕在线观看 | 免费三级av | 在线精品视频在线观看高清 | 国产色拍拍拍拍在线精品 | 黄色av网站在线免费观看 | 区一区二区三在线观看 | 欧美精品久久久久久久久久丰满 | 99热精品国产一区二区在线观看 | 欧美日韩免费一区二区三区 | 日韩激情视频在线 | 国产无遮挡又黄又爽馒头漫画 | av黄色大片 | av再线观看 | 国产尤物一区二区三区 | 99999精品 | 91手机电视 | 日批网站在线观看 | 久久久久国产精品午夜一区 | 婷婷在线五月 | av在线成人 | 在线a人片免费观看视频 | 色婷婷狠狠 | 精品一区电影 | 国产日韩精品在线观看 | 在线天堂中文在线资源网 | 国产成人精品综合 | 国产中文字幕91 | 国产极品尤物在线 | 欧美中文字幕第一页 | 福利一区在线 | 黄色影院在线播放 | 中文字幕免费高清在线观看 | 亚洲草视频 | 亚洲自拍偷拍色图 | 激情av资源 | 久久久久久久久久久久久9999 | 一区二区亚洲精品 | 久久久麻豆精品一区二区 | av一区在线 | 91精品亚洲影视在线观看 | 久久国产片| 91麻豆精品国产91久久久无限制版 | 久久久麻豆精品一区二区 | 五月婷婷综合在线视频 | 国产精品 国产精品 | 免费黄色在线播放 | 国产一区二区在线播放 | 天天色天天干天天色 | 亚洲精品欧美视频 | 欧美91精品久久久久国产性生爱 | 国产91学生| 天堂在线v | 最近日本韩国中文字幕 | 全久久久久久久久久久电影 | 久久国产精品第一页 | 欧美欧美 | 亚洲综合在线一区二区三区 | 特黄特色特刺激视频免费播放 | 激情欧美在线观看 | 日韩在线免费观看视频 | 久久久久久久久久久成人 | 成人黄色毛片视频 | 久久免费激情视频 | 久久综合影视 | 久草视频手机在线 | 国产精品一区二区 91 | 久久天天躁狠狠躁亚洲综合公司 | 天海翼一区二区三区免费 | 18女毛片| 伊人夜夜| 日韩久久久久久 | 久久不射影院 | 欧美色操 | 欧美三级高清 | 日韩在线免费播放 | h久久| 欧美久久电影 | 亚洲va男人天堂 | 国产香蕉视频在线观看 | 亚洲涩综合 | 91九色网站| 欧美精品一区二区免费 | 97国产电影| 成人h动漫在线看 | 国产一级免费在线观看 | 人人操日日干 | 日韩一区正在播放 | 亚洲精品男人天堂 | 最新av网址在线 | 日韩av电影国产 | www日韩| 亚洲伊人天堂 | 五月婷婷色播 | 夜夜躁日日躁狠狠久久av | 免费三及片 | 日韩激情av在线 | 欧美精品二| 中文字幕第一 | 91久久精品一区 | 久久久久一区 | 久久免费公开视频 | av在观看 | 手机成人在线 | 精品在线观看一区二区 | a视频在线观看免费 | 久久久国产一区二区 | 伊人中文字幕在线 | 一区免费在线 | 国产午夜一区二区 | 日日干av | 91精品中文字幕 | 成人久久免费视频 | 久久九九影视 | 国产一级二级在线播放 | 久久久国产一区 | 久久69精品 | 日本精品久久 | 91麻豆操| 国产成人精品在线播放 | 国产精品白浆视频 | 国色天香在线 | 亚洲 欧美变态 另类 综合 | 国产精品免费久久 | 欧美日韩国产一区二区三区在线观看 | 一区三区视频在线观看 | 久久视频免费观看 | 日韩中字在线 | 久久免费精品视频 | 九九热久久免费视频 | 成人黄色免费观看 | 国产在线一卡 | 日本九九视频 | 亚洲黄色在线看 | 国产精品久久影院 | 色婷婷丁香| 久久高清片 | 亚洲 在线 | 日日夜夜人人精品 | 亚洲h在线播放在线观看h | 中文字幕免费高清av | 午夜视频一区二区三区 | 丰满少妇一级 | 日韩精品视频网站 | 免费观看丰满少妇做爰 | 99热只有精品在线观看 | 丁香激情五月婷婷 | 亚洲人视频在线 | 麻豆va一区二区三区久久浪 | 天天操天天操天天操天天操天天操 | 在线天堂中文在线资源网 | 国产精品1区 | 插综合网 | 成人免费在线网 | 欧美视频不卡 | 在线亚洲欧美日韩 | 国产成人精品国内自产拍免费看 | 欧美一级视频一区 | 99久国产 | 91自拍91| 国产成人精品一区二区三区免费 | ,久久福利影视 | 在线看av的网址 | 在线免费中文字幕 | 成人免费看电影 | 久久短视频 | 黄色三级免费片 | 国产精品综合久久久 | 久久精品视频日本 | 永久免费视频国产 | 久九视频| 91在线视频免费播放 | 亚洲日本在线一区 | 国产在线播放一区二区三区 | 日韩精品视| 亚洲男男gaygay无套 | 久久久精品二区 | 亚洲理论电影 | 日韩网站在线播放 | 亚洲精品在线播放视频 | 欧美-第1页-屁屁影院 | 日日夜夜艹 | 99精品毛片 | 精品久久亚洲 | 91免费在线播放 | www国产在线 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 91精品福利在线 | 一区二区视频播放 | 国产精品久久久久久欧美 | 天天干夜夜想 | 黄色a大片| 国产在线观看你懂得 | 亚av在线 | 日韩字幕| 国产99久久九九精品免费 | 国产精品久久久电影 | 免费男女羞羞的视频网站中文字幕 | 欧洲在线免费视频 | 精品电影一区 | 国内小视频在线观看 | 精品国产诱惑 | 欧美成人999 | 国产午夜精品久久久久久久久久 | 中文字幕视频免费观看 | 黄色日视频 | 成人av免费在线 | 国产999精品久久久久久麻豆 | 中文字幕精品视频 | 不卡的av在线播放 | 91成熟丰满女人少妇 | 国产视频精品视频 | 91精品婷婷国产综合久久蝌蚪 | 亚洲黄色成人网 | 精品极品在线 | 国产黄色在线网站 | 九九九热精品免费视频观看网站 | 国产理论在线 | 国产精品久久久久久久久久久久午夜片 | av片在线观看免费 | 久草在| 久久国产色 | 久久久久久免费 | 91久久偷偷做嫩草影院 | 国产精品涩涩屋www在线观看 | 欧美日韩国产综合网 | 好看av在线 | 91九色自拍 | 高清中文字幕 | 夜夜躁日日躁狠狠躁 | 免费男女网站 | 日韩精品欧美一区 | 免费视频国产 | 亚洲免费在线看 | 四虎影视av | 午夜体验区 | 国产97在线播放 | 日韩欧美在线综合网 | 久久精品视频国产 | 在线观看va | 天天操天天射天天舔 | 99热这里只有精品在线观看 | 亚洲精品玖玖玖av在线看 | 国产视频1| 成人黄色大片 | 在线视频免费观看 | 一区二区三区日韩在线观看 | 成人av网站在线观看 | 亚洲天天干 | 天天爽综合网 | 国产亚洲精品久久久久久大师 | 日韩久久片 | 精品一区二区久久久久久久网站 | 免费a视频在线 | 天天干,夜夜操 | 精品96久久久久久中文字幕无 | 国产精品粉嫩 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 亚洲专区欧美专区 | 99在线精品视频在线观看 | 成人h电影在线观看 | 国产九九九九九 | 97成人免费视频 | 超碰97.com | 久久精品电影网 | 玖玖视频 | 欧美日韩中文字幕视频 | av黄色免费在线观看 | 在线va网站 | 久久国产精品久久精品 | 伊人资源视频在线 | 国产韩国日本高清视频 | 五月婷婷网站 | 射久久久 | 欧美有色 | 国产精品99久久免费观看 | 黄色小说视频在线 | 久久久久久激情 | 天天拍天天操 | 看片的网址 | 91完整版 | 国产精品成人免费一区久久羞羞 | 欧美在线视频一区二区三区 | 国产精品女主播一区二区三区 | 在线 视频 一区二区 | 成人免费ⅴa | 免费电影一区二区三区 | 美女精品国产 | 免费黄色看片 | 精品91视频| 日本韩国精品在线 | 日韩在线视频免费观看 | 国产亚洲精品av | 黄色成人免费电影 | 国产资源精品在线观看 | 久草观看| 麻豆94tv免费版 | 日韩免费在线 | 婷婷精品国产一区二区三区日韩 | 丁香五月网久久综合 | 一区二区三区四区在线免费观看 | 人人爽人人爽人人片av免 | 久色免费视频 | 国产一区影院 | 日韩高清免费无专码区 | 91精品999| 天天操天天操天天操天天操天天操 | 91精品久久久久久久99蜜桃 | 久草在线视频看看 | 婷婷六月激情 | 久久久久久蜜桃一区二区 | 香蕉色综合 | 欧美日韩电影在线播放 | 中文字幕日本特黄aa毛片 | 人人爱人人做人人爽 | 久久这里有 | 九九综合九九 | 成人黄色电影视频 | 久久手机视频 | 久久一精品 | 欧美精品一区在线 | 天天拍天天草 | 久久99热国产 | 免费看在线看www777 | 一区二区日韩av | 日韩欧美在线视频一区二区 | 日韩精品久久久久久久电影99爱 | 亚洲三级av| 999久久a精品合区久久久 | 久久草网站| 九九视频免费观看视频精品 | av经典在线 | 欧美一级激情 | www色,com| 99在线视频免费观看 | 在线观看日韩中文字幕 | 免费视频区| 500部大龄熟乱视频使用方法 | 国产护士hd高朝护士1 | 成人免费共享视频 | 天天爱天天色 | 香蕉色综合 | 国产流白浆高潮在线观看 | 在线观看亚洲国产精品 | 精品国产美女在线 | 亚州精品在线视频 | 日韩电影一区二区三区在线观看 | 国产一区二区免费在线观看 | 啪一啪在线| 日日麻批40分钟视频免费观看 | 久久久精品视频网站 | 日本在线观看一区二区 | 久久一区二区三区四区 | 久久欧美在线电影 | 欧美 亚洲 另类 激情 另类 | 鲁一鲁影院 | www91在线观看 | 自拍超碰在线 | 精品久久久久久久久久岛国gif | 国产在线高清视频 | 最近2019好看的中文字幕免费 | 又色又爽又激情的59视频 | 天天摸夜夜操 | 欧美激情综合五月色丁香 | 国内精品久久久久国产 | 欧美了一区在线观看 | 最新国产精品久久精品 | 久久99热精品这里久久精品 | 国产色婷婷精品综合在线手机播放 | 二区三区av| 欧美欧美| 欧美另类sm图片 | 99精品国产兔费观看久久99 | 欧美性超爽| 人人藻人人澡人人爽 | 97超碰精品| 国产一级视频 | 欧美日韩国产欧美 | 四川妇女搡bbbb搡bbbb搡 | 青青草国产精品视频 | 久久精品国产成人精品 | 国产精品99久久久 | 中文字幕一区2区3区 | 亚洲国产精品va在线 | 91成人网在线播放 | 亚洲国产精品99久久久久久久久 | 亚洲激情精品 | av综合网址 | 在线99热 | 久久毛片视频 | 国产精品欧美日韩在线观看 | 91字幕| 在线观看一区 | 欧美精品被| 狠狠色丁香久久婷婷综合_中 | 天天综合色天天综合 | 成人羞羞视频在线观看免费 | 视频在线日韩 | 日韩高清一 | 黄色网中文字幕 | 久久久久久久久久网站 | 国产麻豆视频 | 国产 日韩 欧美 中文 在线播放 | 麻豆免费视频观看 | 亚洲高清视频在线观看 | 久久tv | 成人a毛片 | www色com | 综合天天色 | 中文字幕成人在线观看 | 在线观看不卡视频 | 国产又粗又猛又爽又黄的视频先 | 狠狠干网址 | 欧美日韩在线播放一区 | 一二三精品视频 | 国产精品永久免费 | 国产99久久久国产 | 91亚洲精品在线观看 | 美女久久久久久久 | 精品中文字幕在线观看 | 日韩久久电影 | 免费在线观看av | 日韩高清黄色 | 8x8x在线观看视频 | 夜色成人网 | 亚州精品在线视频 | 91视频91色| 高清精品视频 | 国产黄网在线 | 欧美视频一区二 | 国产在线成人 | 亚洲国产精品一区二区尤物区 | 成人在线播放视频 | 91精品免费 | 国产精品一级在线 | avhd高清在线谜片 | 一区二区三区三区在线 | 日韩欧美视频免费看 | 天天干天天玩天天操 | 国产99久久久国产精品 | 日本mv大片欧洲mv大片 | www.五月天色 | 成人av动漫在线 | 日韩欧美综合在线视频 | 日韩精品一区二区三区第95 | 久久视频精品 | 亚洲伦理电影在线 | 97超碰在线久草超碰在线观看 | 亚洲一区 av | 草久久久久 | 久久久久久久久久久久久久av | 亚洲 欧洲 国产 日本 综合 | 在线91播放 | 久草免费色站 | 国产视频色 | 深夜福利视频在线观看 | 99中文字幕在线观看 | 日韩精品三区四区 | 日韩一级电影在线 | 精品国产成人在线影院 | 一级片黄色片网站 | 久久久精品欧美一区二区免费 | 成人毛片久久 | 在线看毛片网站 | 日本性高潮视频 | 亚洲免费不卡 | 成年人免费在线播放 | 国产亚洲一级高清 | 永久免费毛片在线观看 | 97电影网手机版 | 精品中文字幕在线播放 | 国产色久| 日本三级国产 | 999成人| 中文字幕在线资源 | 亚洲 欧美 日韩 综合 | 69性欧美|