Spring 學習筆記

      網友投稿 629 2025-04-02

      spring介紹


      spring 是一個開源框架,是一個分層的 JavaEE 一站式框架。

      所謂一站式框架是指 Spring 有 JavaEE 開發的每一層解決方案。

      WEB層:SpringMVC

      Service層:Spring的Bean管理,聲明式事務

      DAO層:Spring的JDBC模板,ORM模板

      優點:

      IOC:方便解耦合

      AOP:對程序進行擴展

      輕量級框架

      方便與其他框架整合

      Spring使用

      Spring開發包解壓后的目錄介紹:

      docs: Spring 開發規范和API

      libs: Spring jar 包和源代碼

      schema: Spring 配置文件的約束

      DataAccess 用于數據訪問,WEB 用于頁面顯示,核心容器也就是IOC部分。

      控制反轉(IOC)

      控制反轉(Inversion of Control)是指將對象的創建權反轉(交給)Spring。

      使用IOC就需要導入IOC相關的包,也就是上圖中核心容器中的幾個包:beans,context,core,expression四個包。

      實現原理

      傳統方式創建對象:

      UserDAO userDAO=new UserDAO();

      進一步面向接口編程,可以多態:

      UserDAO userDAO=new UserDAOImpl();

      這種方式的缺點是接口和實現類高耦合,切換底層實現類時,需要修改源代碼。程序設計應該滿足OCP元祖,在盡量不修改程序源代碼的基礎上對程序進行擴展。此時,可以使用工廠模式:

      class BeanFactory{

      public static UserDAO getUserDAO(){

      return new UserDAOImpl();

      }

      }

      此種方式雖然在接口和實現類之間沒有耦合,但是接口和工廠之間存在耦合。

      使用工廠+反射+配置文件的方式,實現解耦,這也是 Spring 框架 IOC 的底層實現。

      //xml配置文件

      //

      class BeanFactory{

      public static Object getBean(String id){

      //解析XML

      //反射

      Class clazz=Class.forName();

      return clazz.newInstance();

      }

      }

      IOC XML 開發

      在 docs 文件中包含了 xsd-configuration.hmtl 文件。其中定義了 beans schema。

      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

      調用類:

      ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");

      UserService userService=(UserService)applicationContext.getBean("userService");

      userService.save();

      IOC 和 DI

      DI 指依賴注入,其前提是必須有 IOC 的環境,Spring 管理這個類的時候將類的依賴的屬性注入進來。

      例如,在UserServiceImpl.java中:

      public class UserServiceImpl implements UserService{

      private String name;

      public void setName(String name){

      this.name=name;

      }

      public void save(){

      System.out.println("save "+name);

      }

      }

      在配置文件中:

      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">

      測試代碼:

      @Test

      public void demo2(){

      //創建Spring工廠

      ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");

      UserService userService=(UserService)applicationContext.getBean("userService");

      userService.save();

      }

      運行結果:

      save tony

      可以看到,在配置文件中配置的屬性,在 Spring 管理該類的時候將其依賴的屬性成功進行了設置。如果不使用依賴注入,則無法使用接口,只能使用實現類來進行設置,因為接口中沒有該屬性。

      Spring 的工廠類

      BeanFactory: 老版本的工廠類,在調用getBean()方法時,才會生成類的實例。

      ApplicationContext: 在加載配置文件的時候,就會將 Spring 管理的類都實例化。有兩個實現類:

      ClassPathXmlApplicationContext: 加載類路徑下的配置文件

      FileSystemXmlApplicationContext: 加載磁盤下的配置文件

      bean標簽配置

      id: 唯一約束,不能出現特殊字符

      name: 理論上可以重復,但是開發中最好不要。可以出現特殊字符

      生命周期:

      init-method: bean被初始化的時候執行的方法

      destroy-method: bean被銷毀的時候執行的方法

      作用范圍:

      scope: bean的作用范圍,有如下幾種,常用的是前兩種

      singleton: 默認使用單例模式創建

      prototype: 多例

      request: 在web項目中,spring 創建類后,將其存入到 request 范圍中

      session: 在web項目中,spring 創建類后,將其存入到 session 范圍中

      globalsession: 在web項目中,必須用在 porlet 環境

      屬性注入設置

      構造方法方式的屬性注入: Car 類在構造方法中有兩個屬性,分別為 name 和 price。

      set 方法屬性注入: Employee 類在有兩個 set 方法,分別設置普通類型的 name 和引用類型的 Car (使用 ref 指向引用類型的 id 或 ?name)。

      P名稱空間的屬性注入: 首先需要引入p名稱空間:

      //引入p名稱空間

      xmlns:p="http://www.springframework.org/schema/p"

      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">

      如果是普通屬性:

      如果是引用類型:

      SpEL(Spring Expression Language)屬性注入(Spring 3.x以上版本)

      集合類型屬性注入:

      qirui

      baoma

      benchi

      多模塊開發配置

      在加載配置文件的時候,加載多個配置文件

      在一個配置文件中引入多個配置文件,通過實現

      IOC 注解開發

      示例

      引入jar包: 除了要引入上述的四個包之外,還需要引入aop包。

      創建 applicationContext.xml ,使用注解開發引入 context 約束(xsd-configuration.html)

      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.xsd

      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

      組件掃描: 使用IOC注解開發,需要配置組件掃描,也就是哪些包下的類使用IOC的注解。

      在類上添加注解

      使用注解設置屬性的值

      屬性如果有set方法,將屬性注入的注解添加到set方法

      屬性沒有set方法,將注解添加到屬性上。

      @Component("UserDao")//相當于配置了一個 其id為UserDao,對應的類為該類

      public class UserDAOImpl implements UserDAO {

      @Override

      public void save() {

      // TODO Auto-generated method stub

      System.out.println("save");

      }

      }

      注解詳解

      @Component

      組件注解,用于修飾一個類,將這個類交給 Spring 管理。

      有三個衍生的注解,功能類似,也用來修飾類。

      @Controller:修飾 web 層類

      @Service:修飾 service 層類

      @Repository:修飾 dao 層類

      2.屬性注入

      普通屬性使用 @Value 來設置屬性的值

      對象屬性使用 @Autowired ?,這個注解是按照類型來進行屬性注入的。如果希望按照 bean 的名稱或id進行屬性注入,需要用 @Autowired 和 @Qualifier 一起使用

      實際開發中,使用 @Resource(name=" ") 來進行按照對象的名稱完成屬性注入

      3.其他注解

      @PostConstruct 相當于 init-method,用于初始化函數的注解

      @PreDestroy 相當于 destroy-method,用于銷毀函數的注解

      @Scope 作用范圍的注解,常用的是默認單例,還有多例 @Scope("prototype")

      IOC 的 XML 和注解開發比較

      適用場景:XML 適用于任何場景;注解只適合自己寫的類,不是自己提供的類無法添加注解。

      可以使用 XML 管理 bean,使用注解來進行屬性注入

      AOP開發

      AOP 是 Aspect Oriented Programming 的縮寫,意為面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術,是OOP的延續。

      AOP 能夠對程序進行增強,在不修改源碼的情況下,可以進行權限校驗,日志記錄,性能監控,事務控制等。

      也就是說功能分為兩大類,一類是核心業務功能,一類是輔助增強功能。兩類功能彼此獨立進行開發。比如登錄功能是核心業務功能,日志功能是輔助增強功能,如果有需要,將日志和登錄編制在一起。輔助功能就稱為切面,這種能選擇性的、低耦合的把切面和核心業務功能結合的編程思想稱為切面編程。

      底層實現

      JDK 動態代理只能對實現了接口的類產生代理。Cglib 動態代理可以對沒有實現接口的類產生代理對象,生成的是子類對象。

      使用 JDK 動態代理:

      public interface UserDao {

      public void insert();

      public void delete();

      public void update();

      public void query();

      }

      實現類:

      public class UserDaoImpl implements UserDao { @Override public void insert() { System.out.println("insert"); } @Override public void delete() { System.out.println("delete"); } @Override public void update() { System.out.println("update"); } @Override public void query() { System.out.println("query"); } }

      JDK 代理:

      public class JDKProxy implements InvocationHandler{

      private UserDao userDao;

      public JDKProxy(UserDao userDao){

      this.userDao=userDao;

      }

      public UserDao createProxy(){

      UserDao userDaoProxy=(UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),

      userDao.getClass().getInterfaces(), this);

      return userDaoProxy;

      }

      @Override

      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

      if("update".equals(method.getName())){

      System.out.println("權限校驗");

      return method.invoke(userDao, args);

      }

      return method.invoke(userDao, args);

      }

      }

      通過動態代理增強了 update 函數。 測試類:

      public class Demo1 {

      @Test

      public void demo1(){

      UserDao userDao=new UserDaoImpl();

      UserDao proxy=new JDKProxy(userDao).createProxy();

      proxy.insert();

      proxy.delete();

      proxy.update();

      proxy.query();

      }

      }

      運行結果為:

      insert

      delete

      權限校驗

      update

      query

      CglibCglib 是第三方開源代碼生成類庫,可以動態添加類的屬性和方法。

      與上邊JDK代理不同,Cglib的使用方式如下:

      public class CglibProxy implements MethodInterceptor{

      //傳入增強的對象

      private UserDao customerDao;

      public CglibProxy(UserDao userDao){

      this.userDao=userDao;

      }

      public UserDao createProxy(){

      Enhancer enhancer=new Enhancer();

      enhancer.setSuperclass(userDao.getClass());

      enhancer.setCallback(this);

      UserDao proxy=(UserDao)enhancer.create();

      return proxy;

      }

      @Override

      public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

      if("save".equals(method.getName())){

      System.out.println("enhance function");

      return methodProxy.invokeSuper(proxy, args);

      }

      return methodProxy.invokeSuper(proxy, args);

      }

      }

      如果實現了接口的類,底層采用JDK代理。如果不是實現了接口的類,底層采用 Cglib代理。

      IOC與傳統方式的比較

      獲取對象方式:傳統通過 new 關鍵字主動創建一個對象。IOC 方式中,將對象的生命周期交給 Spring 管理,直接從 Spring 獲取對象。也就是控制反轉————將控制權從自己手中交到了 Spring 手中。

      Spring 的 AOP 開發(AspectJ 的 XML 方式)

      AspectJ 是一個 AOP 的框架,Spring 引入 AspectJ,基于 AspectJ 進行 AOP 的開發。

      相關術語

      Joinpoint: 連接點,可以被攔截到的點。也就是可以被增強的方法都是連接點。

      Pointcut: 切入點,真正被攔截到的點,也就是真正被增強的方法

      Advice: 通知,方法層面的增強。對某個方法進行增強的方法,比如對 save 方法進行權限校驗,權限校驗的方法稱為通知。

      Introduction: 引介,類層面的增強。

      Target: 目標,被增強的對象(類)。

      Weaving: 織入,將 advice 應用到 target 的過程。

      Proxy: 代理對象,被增強的對象。

      Aspect: 切面,多個通知和多個切入點的組合。

      使用方法

      引入相關包

      引入配置文件

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="

      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

      編寫目標類并配置:

      public class ProductDaoImpl implements ProductDao {

      @Override

      public void save() {

      System.out.println("save");

      }

      @Override

      public void update() {

      System.out.println("update");

      }

      @Override

      public void find() {

      System.out.println("find");

      }

      @Override

      public void delete() {

      System.out.println("delete");

      }

      }

      編寫切面類,假設用于權限驗證并配置

      public class MyAspectXML {

      public void checkPri(){

      System.out.println("check auth");

      }

      }

      通過AOP配置完成對目標類的增強

      通知類型

      前置通知:在目標方法執行前操作,可以獲得切入點信息

      public void checkPri(JoinPoint joinPoint){

      System.out.println("check auth "+joinPoint);

      }

      后置通知:在目標方法執行后操作,可以獲得方法返回值

      public void writeLog(Object result){

      System.out.println("writeLog "+result);

      }

      環繞通知:在目標方法執行前和后操作,可以阻止目標方法執

      public Object around(ProceedingJoinPoint joinPoint) throws Throwable{

      System.out.println("before");

      Object result=joinPoint.proceed();

      System.out.println("after");

      return result;

      }

      異常拋出通知:程序出現異常時操作

      public void afterThrowing(Throwable ex){

      System.out.println("exception "+ex.getMessage());

      }

      最終通知:相當于finally塊,無論代碼是否有異常,都會執行

      public void finallyFunc(){

      System.out.println("finally");

      }

      引介通知:不常用

      Spring 切入點表達式

      基于 execution 函數完成

      語法:[訪問修飾符] 方法返回值 包名.類名.方法名(參數)

      其中任意字段可以使用*代替表示任意值

      Spring 的 AOP 基于 AspectJ 注解開發

      開發步驟

      引入jar包

      設置配置文件:

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:context="http://www.springframework.org/schema/context"

      xmlns:aop="http://www.springframework.org/schema/aop"

      xmlns:tx="http://www.springframework.org/schema/tx"

      xsi:schemaLocation="http://www.springframework.org/schema/beans

      http://www.springframework.org/schema/beans/spring-beans.xsd

      http://www.springframework.org/schema/context

      http://www.springframework.org/schema/context/spring-context.xsd

      http://www.springframework.org/schema/aop

      http://www.springframework.org/schema/aop/spring-aop.xsd

      http://www.springframework.org/schema/tx

      http://www.springframework.org/schema/tx/spring-tx.xsd">

      編寫配置目標類

      public class OrderDao {

      public void save(){

      System.out.println("save order");

      }

      public void update(){

      System.out.println("update order");

      }

      public void delete(){

      System.out.println("delete order");

      }

      public void find(){

      System.out.println("find order");

      }

      }

      開啟aop注解自動代理

      編寫切面類并配置

      @Aspect

      public class MyAspectAnno {

      @Before(value="execution(* demo1.OrderDao.save(..))")

      public void before(){

      System.out.println("before");

      }

      }

      注解通知類型

      @Before: 前置通知

      @AfterReturning: 后置通知

      @AfterReturning(value="execution(* demo1.OrderDao.save(..))",returning="result")

      public void after(Object result){

      System.out.println("after "+result);

      }

      @Around:環繞通知

      @Around(value="execution(* demo1.OrderDao.save(..))")

      public Object around(ProceedingJoinPoint joinPoint) throws Throwable{

      System.out.println("before");

      Object obj=joinPoint.proceed();

      System.out.println("after");

      return obj;

      }

      @AfterThrowing: 拋出異常

      @AfterThrowing(value="execution(* demo1.OrderDao.save(..))",throwing="e")

      public void afterThrowing(Throwable e){

      System.out.println("exception:"+e.getMessage();

      }

      @After: 最終通知

      @After(value="execution(* demo1.OrderDao.save(..))")

      public void after(){

      System.out.println("finally");

      }

      @PointCut:切入點注解

      @PointCut(value="execution(* demo1.OrderDao.save(..))")

      private void pointcut1(){}

      此時,在上述通知的注解中,value可以替換為該函數名,例如:

      @After(value="MyAspect.pointcut1()")

      public void after(){

      System.out.println("finally");

      }

      這個注解的好處是,只需要維護切入點即可,不用在修改時修改每個注解。

      Spring 的 JDBC 模板

      Spring 對持久層也提供了解決方案,也就是 ORM 模塊和 JDBC 的模板。針對 JDBC ,提供了 org.springframework.jdbc.core.JdbcTemplate 作為模板類。

      使用 JDBC 模板

      引入jar包,數據庫驅動,Spring 的 jdbc 相關包。

      基本使用:

      public void demo1(){

      //創建連接池

      DriverManagerDataSource dataSource=new DriverManagerDataSource();

      dataSource.setDriverClassName("com.mysql.jdbc.Driver");

      dataSource.setUrl("jdbc:mysql:///spring4");

      dataSource.setUsername("root");

      dataSource.setPassword("123456");

      //創建JDBC模板

      JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);

      jdbcTemplate.update("insert into account values (null,?,?)", "xiaoming",1000d);

      }

      將連接池和模板交給 Spring 管理

      配置文件:

      測試文件:

      @RunWith(SpringJUnit4ClassRunner.class)

      @ContextConfiguration("classpath:applicationContext.xml")

      public class JdbcDemo2 {

      @Resource(name="jdbcTemplate")

      private JdbcTemplate jdbcTemplate;

      @Test

      public void demo2(){

      jdbcTemplate.update("insert into account values (null,?,?)", "xiaolan",1000d);

      }

      }

      使用開源數據庫連接池

      使用 DBCP 的配置:

      使用 C3P0 的配置:

      引入外部屬性文件

      首先建立外部屬性文件:

      jdbc.driverClass=com.mysql.jdbc.Driver

      jdbc.url=jdbc:mysql://192.168.66.128/spring4

      jdbc.username=root

      jdbc.password=123456

      然后對屬性文件進行配置:

      CRUD操作

      insert, update, delete 語句都借助模板的 update 方法進行操作。

      public void demo(){

      jdbcTemplate.update("insert into account values (null,?,?)", "xiaoda",1000d);

      jdbcTemplate.update("update account set name=?,money=? where id=?", "xiaoda",1000d,2);

      jdbcTemplate.update("delete from account where id=?", 6);

      }

      查詢操作:

      public void demo3(){

      String name=jdbcTemplate.queryForObject("select name from account where id=?",String.class,5);

      long count=jdbcTemplate.queryForObject("select count(*) from account",Long.class);

      }

      將返回的結果封裝成為類:

      public void demo4(){

      Account account=jdbcTemplate.queryForObject("select * from account where id=?", new MyRowMapper(),5);

      }

      其中:

      class MyRowMapper implements RowMapper{

      @Override

      public Account mapRow(ResultSet rs, int rowNum) throws SQLException {

      Account account=new Account();

      account.setId(rs.getInt("id"));

      account.setName(rs.getString("name"));

      account.setMoney(rs.getDouble("money"));

      return account;

      }

      }

      Spring的事務管理

      事務

      事務是指邏輯上的一組操作,組成這組操作的各個單元,要么全部成功,要么全部失敗。

      具有四個特性:

      原子性:事務不可分

      一致性:事務執行前后數據完整性保持一致

      隔離性:一個事務的執行不應該受到其他事務干擾

      持久性:一旦事務結束,數據就持久化到數據庫

      如果不考慮隔離性會引發安全性問題:

      讀問題:

      臟讀:一個事務讀到另一個事務未提交的數據

      不可重復讀:一個事務讀到另一個事務已經提交的 update 數據,導致一個事務中多次查詢結果不一致

      幻讀:一個事務讀到另一個事務已經提交的 insert 數據,導致一個事務中多次查詢結果不一致

      寫問題:

      丟失更新

      解決讀問題:設置事務隔離級別

      Read uncommitted: 未提交讀,無法解決任何讀問題

      Read committed: 已提交讀,解決臟讀問題

      Repeatable read: 重復讀,解決臟讀和不可重復讀問題

      Serializable:序列化,解決所有讀問題

      事務管理API

      PlatformTransactionManager: 平臺事務管理器

      這是一個接口,擁有多個不同的實現類,如 DataSourceTransactionManager 底層使用了JDBC 管理事務; HibernateTransactionManager 底層使用了 Hibernate 管理事務。

      TransactionDefinition: 事務定義信息

      用于定義事務的相關信息,如隔離級別、超時信息、傳播行為、是否只讀等

      TransactionStatus: 事務的狀態

      用于記錄在事務管理過程中,事務的狀態的對象。

      上述API的關系: Spring 在進行事務管理的時候,首先平臺事務管理器根據事務定義信息進行事務管理,在事務管理過程當中,產生各種此狀態,將這些狀態信息記錄到事務狀態的對象當中。

      事務的傳播行為

      事務的傳播行為主要解決業務層(Service)方法相互調用的問題,也就是不同的業務中存在不同的事務時,如何操作。

      Spring 中提供了7種事務的傳播行為,分為三類:

      保證多個操作在同一個事務中

      PROPAGATION_REQUIRED: B方法調用A方法,如果A中有事務,使用A中的事務并將B中的操作包含到該事務中;否則新建一個事務,將A和B中的操作包含進來。(默認)

      PROPAGATION_SUPPORTS:如果A中有事務,使用A的事務;否則不使用事務

      PROPAGATION_MANDATORY:如果A中有事務,使用A的事務;否則拋出異常

      保證多個操作不在同一個事務中

      PROPAGATION_REQUIRES_NEW:如果A中有事務,將其掛起,創建新事務,只包含自身操作。否則,新建一個事務,只包含自身操作。

      PROPAGATION_NOT_SUPPORTED:如果A中有事務,掛起,不使用事務。

      PROPAGATION_NEVER:如果A中有事務,拋出異常,也即不能用事務運行。

      嵌套事務

      PROPAGATION_NESTED:如果A有事務,按照A的事務執行,執行完成后,設置一個保存點,然后執行B的操作。如果出現異常,可以回滾到最初狀態或保存點狀態。

      實例

      以轉賬為例,業務層的DAO層類如下:

      public interface AccountDao {

      public void outMoney(String from,Double money);

      public void inMoney(String to,Double money);

      }

      public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{

      @Override

      public void outMoney(String from, Double money) {

      this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,from);

      }

      @Override

      public void inMoney(String to, Double money) {

      this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,to);

      }

      }

      public interface AccountService {

      Spring 學習筆記

      public void transfer(String from,String to,Double money);

      }

      public class AccountServiceImpl implements AccountService {

      private AccountDao accountDao;

      public void setAccountDao(AccountDao accountDao) {

      this.accountDao = accountDao;

      }

      @Override

      public void transfer(String from, String to, Double money) {

      accountDao.outMoney(from, money);

      accountDao.inMoney(to, money);

      }

      }

      在xml中進行類的配置:

      Spring 容器

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表格數據排序的方法(在excel表格中,數據排序的方式)
      下一篇:轉載】SDK 和 API 的區別是什么?
      相關文章
      日韩亚洲不卡在线视频中文字幕在线观看 | 日韩精品亚洲aⅴ在线影院| 亚洲一区二区无码偷拍| 亚洲不卡中文字幕| 亚洲最新中文字幕| 亚洲国产成人无码av在线播放 | 亚洲乱人伦中文字幕无码| 亚洲中文字幕AV每天更新| 亚洲丰满熟女一区二区v| 亚洲人成影院77777| 亚洲国产亚洲片在线观看播放| 亚洲经典在线中文字幕| 亚洲美女激情视频| 亚洲理论在线观看| 亚洲中文字幕在线无码一区二区| 亚洲人成在线播放| 亚洲综合无码一区二区痴汉| 亚洲综合欧美色五月俺也去| 亚洲精品无码mⅴ在线观看| 亚洲另类无码专区首页| 亚洲av永久中文无码精品| 成人婷婷网色偷偷亚洲男人的天堂| 爱爱帝国亚洲一区二区三区| 亚洲äv永久无码精品天堂久久| 国产亚洲视频在线播放大全| 亚洲国产综合精品中文字幕| 国产亚洲老熟女视频| 亚洲人成网站在线观看播放| 久久久久亚洲精品成人网小说| 亚洲久本草在线中文字幕| 亚洲狠狠狠一区二区三区| 2020久久精品亚洲热综合一本| 亚洲日韩乱码中文字幕| 国产综合激情在线亚洲第一页| 亚洲国产一区二区视频网站| 中文亚洲AV片在线观看不卡| 久久精品国产精品亚洲色婷婷| 亚洲激情视频网站| 亚洲色中文字幕在线播放| 国产成人综合亚洲一区| 伊人久久大香线蕉亚洲|