国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring面向切面編程(AOP)

這篇具有很好參考價(jià)值的文章主要介紹了Spring面向切面編程(AOP)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Spring面向切面編程(AOP)

概念

AOP(Aspect Oriented Programming),即面向切面編程,利用一種稱為"橫切"的技術(shù),剖開封裝的對(duì)象內(nèi)部,并將那些影響了多個(gè)類的公共行為封裝到一個(gè)可重用模塊,并將其命名為"Aspect",即切面。所謂"切面",簡(jiǎn)單說就是那些與業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊之間的耦合度,并有利于未來的可操作性和可維護(hù)性。

什么是AOP

面向切面編程:利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使業(yè)務(wù)邏輯的各部分之間耦合度降低,提高程序的可重用性,提高了開發(fā)效率,通俗的講,可以實(shí)現(xiàn)不修改源代碼的方式,在核心業(yè)務(wù)里面 添加新的功能。

AOP底層的原理就是動(dòng)態(tài)代理 ,真正干活的 bean 是 代理 bean , 代理 bean 對(duì)真實(shí) bean 功能增強(qiáng)。

AOP開發(fā)術(shù)語

  • 連接點(diǎn)(Joinpoint):連接點(diǎn)是程序類中客觀存在的方法,可被Spring攔截并切入內(nèi)容
    • 說白了,類中的哪些方法可以被增強(qiáng),這些方法就稱為是連接點(diǎn)
  • 切入點(diǎn)(Pointcut):被Spring切入連接點(diǎn)
    • 真正被增強(qiáng)的方法稱為切入點(diǎn)
  • 通知、增強(qiáng)(Advice):可以為切入點(diǎn)添加額外功能,分為:前置通知、后置通知、異常通知、環(huán)繞通知,最終通知等
    • 實(shí)際增強(qiáng)的邏輯部分,稱為通知(增強(qiáng))
  • 目標(biāo)對(duì)象(Target):代理的目標(biāo)對(duì)象,真實(shí)對(duì)象
  • 引介(Introduction):一種特殊的增強(qiáng),可在運(yùn)行期為類動(dòng)態(tài)添加Field和Method
  • 織入(Weaving):把通知應(yīng)用到具體的類,進(jìn)而創(chuàng)建新的代理類的過程
  • 代理(Proxy):被AOP織入通知后,產(chǎn)生的結(jié)果類
  • 切面(Aspect):由切點(diǎn)和通知組成,將橫切邏輯織入切面所指定的連接點(diǎn)中。 把通知 應(yīng)用到 切入點(diǎn)的過程

作用

Spring的AOP編程即是通過動(dòng)態(tài)代理類為原始類的方法添加輔助功能

開發(fā)流程

環(huán)境搭建

引入AOP相關(guān)依賴

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.1.6.RELEASE</version>
</dependency>

spring-context.xml引入AOP命名空間

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       ">
</beans>
代碼演示

定義原始類

public interface UserService {
    public void save();
}
public class UserServiceImpl implements UserService {
    public void save() {
        System.out.println("save method executed...");
    }
}
基于Schema-based實(shí)現(xiàn)AOP

定義通知類(添加額外功能)

//實(shí)現(xiàn)前置通知接口
public class MyAdvice implements MethodBeforeAdvice { 
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("before advice executed...");
    }
}

定義bean標(biāo)簽

<!--原始對(duì)象-->
<bean id="us" class="com.qf.aaron.aop.basic.UserServiceImpl" />

<!--輔助對(duì)象-->
<bean id="myAdvice" class="com.qf.aaron.aop.basic.MyAdvice" />

定義切入點(diǎn)(PointCut),形成切面(Aspect)

<aop:config>
    <!--切點(diǎn)-->
    <aop:pointcut id="myPointCut" expression="execution(* save())" />
    <!--組裝切面 -->
    <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointCut" />
</aop:config>
基于AspectJ 實(shí)現(xiàn)AOP

創(chuàng)建 通知類

/**
 * @ClassName : MyAspectJAdvice

 * @Description :   AspectJ 的 通知類  無需實(shí)現(xiàn)接口
 */
public class MyAspectJAdvice {

    public void before(){
        System.out.println("前置增強(qiáng)代碼");
    }

    public Object around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("環(huán)繞增強(qiáng)前面的代碼");
        // 讓目標(biāo)方法繼續(xù)執(zhí)行
        Object result = jp.proceed();
        System.out.println("環(huán)繞增強(qiáng)后面的代碼");
        return result;
    }


    public void after(){
        System.out.println("最終增強(qiáng)的代碼,類似于finally,目標(biāo)方法有沒有異常都要執(zhí)行的");
    }


    public void throwing(Exception e){
        System.out.println("異常拋出增強(qiáng)代碼,只有在目標(biāo)方法拋出異常時(shí)才能執(zhí)行");
        System.out.println("異常信息是:" + e.getMessage());
    }

    public void afterReturning(Object result){
        System.out.println("后置增強(qiáng),返回值是:"+result);
    }
}

xml 配置

<?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:aop="http://www.springframework.org/schema/aop"
       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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 其他bean的定義... -->

    <!--了解 基于 AspectJ 的 xml 的  AOP實(shí)現(xiàn) 配置-->

    <!-- 配置增強(qiáng)類 -->
    <bean id="advice" class="com.qf.spring.aop.advice.MyAspectJAdvice" />

    <!-- 配置AOP -->
    <aop:config>
        <!-- 配置切入點(diǎn) -->
        <aop:pointcut id="pc" expression="execution(* save())"/>
        <aop:aspect ref="advice">
            <!-- aop:before 前置增強(qiáng)的配置 -->
            <aop:before method="before" pointcut-ref="pc" />
            <!-- 環(huán)繞目標(biāo)方法執(zhí)行 -->
            <aop:around method="around" pointcut-ref="pc" />
            <!-- 異常拋出增強(qiáng) -->
            <aop:after-throwing method="throwing" pointcut-ref="pc" throwing="e" />
            <!-- 最終增強(qiáng) -->
            <aop:after method="after" pointcut-ref="pc" />
            <!-- 后置增強(qiáng),目標(biāo)方法拋出異常時(shí) 后置增強(qiáng)不執(zhí)行 -->
            <aop:after-returning method="afterReturning" pointcut-ref="pc" returning="result"/>
        </aop:aspect>

    </aop:config>

</beans>

測(cè)試

	@Test
	void save() {
	   ApplicationContext context = new ClassPathXmlApplicationContext("/beans.xml");
	   UserService service = context.getBean(UserService.class);
	   service.save();
	}

AOP小結(jié)

  • 通過AOP提供的編碼流程,更便利的定制切面,更方便的定制了動(dòng)態(tài)代理
  • 進(jìn)而徹底解決了輔助功能冗余的問題
  • 業(yè)務(wù)類中職責(zé)單一性得到更好保障
  • 輔助功能也有很好的復(fù)用性

通知類【可選】

定義通知類,達(dá)到通知效果

前置通知:MethodBeforeAdvice

后置通知:AfterAdvice

后置通知:AfterReturningAdvice //有異常不執(zhí)行,方法會(huì)因異常而結(jié)束,無返回值

異常通知:ThrowsAdvice

環(huán)繞通知:MethodInterceptor

沒有必要把通知的執(zhí)行順序記得非常精確,因?yàn)?spring 新版本 5 和 之前的舊版本 通知的執(zhí)行順序 不一樣

通配切入點(diǎn)【可選】

根據(jù)表達(dá)式通配切入點(diǎn)

<!--匹配參數(shù)-->
<aop:pointcut id="myPointCut" expression="execution(* *(com.qf.aaron.aop.basic.User))" />
<!--匹配方法名(無參)-->
<aop:pointcut id="myPointCut" expression="execution(* save())" />
<!--匹配方法名(任意參數(shù))-->
<aop:pointcut id="myPointCut" expression="execution(* save(..))" />
<!--匹配返回值類型-->
<aop:pointcut id="myPointCut" expression="execution(com.qf.aaron.aop.basic.User *(..))" />
<!--匹配類名-->
<aop:pointcut id="myPointCut" expression="execution(* com.qf.aaron.aop.basic.UserServiceImpl.*(..))" />
<!--匹配包名-->
<aop:pointcut id="myPointCut" expression="execution(* com.qf.aaron.aop.basic.*.*(..))" />
<!--匹配包名、以及子包名-->
<aop:pointcut id="myPointCut" expression="execution(* com.qf.aaron.aop..*.*(..))" />

切入點(diǎn)表達(dá)式:expression 知道對(duì)哪個(gè)類的那個(gè)方法進(jìn)行增強(qiáng)
語法結(jié)構(gòu): execution([權(quán)限修飾符] [返回值類型] [類全路徑] [方法名稱] ([參數(shù)列表])

JDK和CGLIB選擇【可選】

  • spring底層,包含了jdk代理和cglib代理兩種動(dòng)態(tài)代理生成機(jī)制
  • 基本規(guī)則是:目標(biāo)業(yè)務(wù)類如果有接口則用JDK代理,沒有接口則用CGLib代理
class DefaultAopProxyFactory{
    // 該方法中明確定義了 JDK代理和CGLib代理的選取規(guī)則
    // 基本規(guī)則是:目標(biāo)業(yè)務(wù)類如果有接口則用JDK代理,沒有接口則用CGLib代理
    public AopProxy createAopProxy(){...}
}

后處理器【可選】

  • spring中定義了很多后處理器
  • 每個(gè)bean在創(chuàng)建完成之前 ,都會(huì)有一個(gè)后處理過程,即再加工,對(duì)bean做出相關(guān)改變和調(diào)整
  • spring-AOP中,就有一個(gè)專門的后處理器,負(fù)責(zé)通過原始業(yè)務(wù)組件(Service),再加工得到一個(gè)代理組件
    Spring面向切面編程(AOP)

后處理器定義

/**
 * 定義bean后處理器
 * 作用:在bean的創(chuàng)建之后,進(jìn)行再加工
 */
public class MyBeanPostProcessor implements BeanPostProcessor{

    /**
     * 在bean的init方法之前執(zhí)行
     * @param bean  原始的bean對(duì)象
     * @param beanName
     * @return
     * @throws BeansException
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后處理器 在init之前執(zhí)行```"+bean.getClass());
        return bean;
    }
	/**
     * 在bean的init方法之后執(zhí)行
     * @param bean  postProcessBeforeInitialization返回的bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后處理器 在init之后執(zhí)行```"+bean.getClass());
        return bean;// 此處的返回是 getBean() 最終的返回值
    }
}

配置后處理器

<!-- 配置后處理器,將對(duì)工廠中所有的bean聲明周期進(jìn)行干預(yù) -->
<bean class="com.qianfeng.beanpostprocessor.MyBeanPostProcessor"></bean>

bean的生命周期

bean 對(duì)象從創(chuàng)建到銷毀的過程

  • bean 的實(shí)例化 通過構(gòu)造方法創(chuàng)建bean 的實(shí)例 默認(rèn)是無參構(gòu)造
  • 給bean 的屬性賦值
  • 執(zhí)行初始化的方法
  • 得到完整的bean 對(duì)象 ,這時(shí)的bean 對(duì)象才能夠使用
  • 銷毀bean

要考慮 bean 的后置處理器 BeanPostProcessor
創(chuàng)建一個(gè)類實(shí)現(xiàn)BeanPostProcessor 重寫 他的兩個(gè)方法

public class MyBeanPost implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在bean 初始化之前執(zhí)行");

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("在bean初始化之后執(zhí)行");
        if(bean instanceof User){
            User user = (User) bean;
            user.setName("愿天下程序員少走彎路!");
            return user;
        }

        return bean;
    }
}

在配置文件 配置這個(gè) bean

 <bean id="myPostProcessor" class="com.qf.postprocessor.MyBeanPost"></bean>

總結(jié)

  • bean 的實(shí)例化 通過構(gòu)造方法創(chuàng)建bean 的實(shí)例 默認(rèn)是無參構(gòu)造

  • 給bean 的屬性賦值

  • 把 bean 的 實(shí)例 傳遞給 bean的前置處理器的方法 postProcessBeforeInitialization

  • 執(zhí)行初始化的方法

  • 把 bean 的 實(shí)例 傳遞給 bean的后置處理器的方法 postProcessAfterInitialization

  • 得到完整的bean 對(duì)象 ,這時(shí)的bean 對(duì)象才能夠使用

  • 銷毀bean 當(dāng)容器關(guān)閉的時(shí)候 調(diào)用銷毀的方法

    • 自定義初始化方法:添加“init-method”屬性,Spring則會(huì)在創(chuàng)建對(duì)象之后,調(diào)用此方法。
    • 自定義銷毀方法:添加“destroy-method”屬性,Spring則會(huì)在銷毀對(duì)象之前,調(diào)用此方法。
    • 銷毀:工廠的close()方法被調(diào)用之后,Spring會(huì)毀掉所有已創(chuàng)建的單例對(duì)象。
    • 分類:Singleton對(duì)象由Spring容器銷毀、Prototype對(duì)象由JVM銷毀。

生命周期注解(初始化注解、銷毀注解)

@PostConstruct //初始化 
public void init(){
    System.out.println("init method executed");
}

@PreDestroy //銷毀
public void destroy(){
    System.out.println("destroy method executed");
}

生命周期階段
隨工廠啟動(dòng)創(chuàng)建 ==》 構(gòu)造方法 ==》 set方法(注入值) ==》 init(初始化) ==》 構(gòu)建完成 ==》隨工廠關(guān)閉銷毀(單例bean:singleton)
被使用時(shí)創(chuàng)建 ==》 構(gòu)造方法 ==》 set方法(注入值) ==》 init(初始化) ==》 構(gòu)建完成 ==》JVM垃圾回收銷毀(多例bean:prototype)

流程圖
Spring面向切面編程(AOP)

Spring面向切面編程(AOP)
完結(jié)撒花!愿每一位程序員少走彎路是我的創(chuàng)作的初心!文章來源地址http://www.zghlxwxcb.cn/news/detail-467301.html

到了這里,關(guān)于Spring面向切面編程(AOP)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 切面的魔力:解密Spring AOP 面向切面編程

    切面的魔力:解密Spring AOP 面向切面編程

    目錄 一、AOP簡(jiǎn)介 1.1 什么是AOP ? 1.2?什么是面向切面編程 ? 1.3?AOP 的特點(diǎn) 二、?AOP的基本概念解讀 2.1 AOP的基本概念 2.2 AOP 概念趣事解讀 三、代碼情景演示 3.1?編寫目標(biāo)對(duì)象(超級(jí)英雄們正常的行動(dòng)) 3.2 編寫通知類 3.2.1?前置通知 3.2.2 后置通知 3.2.3 異常通知 3.2.4 環(huán)繞通知

    2024年02月11日
    瀏覽(89)
  • JAVA:使用 Spring AOP 實(shí)現(xiàn)面向切面編程

    JAVA:使用 Spring AOP 實(shí)現(xiàn)面向切面編程

    1、簡(jiǎn)述 在現(xiàn)代的軟件開發(fā)中,面向切面編程(AOP)是一種重要的編程范式,它允許我們將橫切關(guān)注點(diǎn)(如日志記錄、性能監(jiān)控、事務(wù)管理等)從應(yīng)用程序的核心業(yè)務(wù)邏輯中分離出來,以提高代碼的模塊化和可維護(hù)性。Spring 框架提供了強(qiáng)大的 AOP 支持,使得我們可以輕松地實(shí)

    2024年04月13日
    瀏覽(31)
  • 【Java 初級(jí)】Spring核心之面向切面編程(AOP)

    【Java 初級(jí)】Spring核心之面向切面編程(AOP)

    tip:作為程序員一定學(xué)習(xí)編程之道,一定要對(duì)代碼的編寫有追求,不能實(shí)現(xiàn)就完事了。我們應(yīng)該讓自己寫的代碼更加優(yōu)雅,即使這會(huì)費(fèi)時(shí)費(fèi)力。 ???? 推薦: 體系化學(xué)習(xí)Java(Java面試專題) AOP(面向切面編程)是一種編程范式,用于將橫切關(guān)注點(diǎn)(如日志記錄、性能統(tǒng)計(jì)等

    2024年02月04日
    瀏覽(28)
  • spring6-AOP面向切面編程

    spring6-AOP面向切面編程

    1、場(chǎng)景模擬 搭建子模塊:spring6-aop 1.1、聲明接口 聲明計(jì)算器接口Calculator,包含加減乘除的抽象方法 1.2、創(chuàng)建實(shí)現(xiàn)類 1.3、創(chuàng)建帶日志功能的實(shí)現(xiàn)類 1.4、提出問題 ①現(xiàn)有代碼缺陷 針對(duì)帶日志功能的實(shí)現(xiàn)類,我們發(fā)現(xiàn)有如下缺陷: 對(duì)核心業(yè)務(wù)功能有干擾,導(dǎo)致程序員在開發(fā)核

    2024年02月08日
    瀏覽(31)
  • 【Spring AOP】結(jié)合日志面向切面編程 兩種寫法

    ??????? 這里需要提前了解什么是Spring的AOP(Aspect Oriented Programming)。是在OOP(面向?qū)ο螅┧枷氲囊环N拓展思想。 簡(jiǎn)單來說就是將某個(gè)代碼塊嵌入到其它的代碼塊中 。筆者先前學(xué)Spring也有學(xué)什么IoC啊AOP啊,但實(shí)際上沒有用過、就那聽過學(xué)過沒啥用的。。沒會(huì)兒就忘記了。

    2024年02月13日
    瀏覽(25)
  • Spring AOP (面向切面編程)原理與代理模式—實(shí)例演示

    Spring AOP (面向切面編程)原理與代理模式—實(shí)例演示

    Spring 中文文檔 (springdoc.cn) Spring | Home 官網(wǎng) ????????Java是一個(gè)面向?qū)ο螅∣OP)的語言,但它有一些弊端。雖然使用OOP可以通過組合或繼承的方式來實(shí)現(xiàn)代碼的重用。但當(dāng)我們需要為多個(gè)不具有繼承關(guān)系的對(duì)象(一般指的是兩個(gè)不同的類,它們之間沒有繼承自同一個(gè)父類或接

    2024年02月15日
    瀏覽(28)
  • Spring AOP使用指南: 強(qiáng)大的面向切面編程技術(shù)

    Spring AOP使用指南: 強(qiáng)大的面向切面編程技術(shù)

    ???? 博主貓頭虎(????)帶您 Go to New World??? ?? 博客首頁 ——????貓頭虎的博客?? ?? 《面試題大全專欄》 ?? 文章圖文并茂??生動(dòng)形象??簡(jiǎn)單易學(xué)!歡迎大家來踩踩~?? ?? 《IDEA開發(fā)秘籍專欄》 ?? 學(xué)會(huì)IDEA常用操作,工作效率翻倍~?? ?? 《100天精通Golang(基礎(chǔ)

    2024年02月09日
    瀏覽(26)
  • 【JavaEE】面向切面編程AOP是什么-Spring AOP框架的基本使用

    【JavaEE】面向切面編程AOP是什么-Spring AOP框架的基本使用

    【JavaEE】 AOP(1) 1.1 AOP 與 Spring AOP AOP ( A spect O riented P rogramming),是一種思想,即 面向切面編程 Spring AOP 則是一個(gè)框架,Spring項(xiàng)目中需要引入依賴而使用 AOP和Spring AOP的關(guān)系就相當(dāng)于IoC和DI Spring AOP讓開發(fā)者能夠半自動(dòng)的開發(fā)AOP思想下實(shí)現(xiàn)的功能 1.2 沒有AOP的世界是怎樣的

    2024年02月11日
    瀏覽(29)
  • 【Spring(十一)】萬字帶你深入學(xué)習(xí)面向切面編程AOP

    【Spring(十一)】萬字帶你深入學(xué)習(xí)面向切面編程AOP

    ??今天我們來學(xué)習(xí) AOP ,在最初我們學(xué)習(xí)Spring時(shí)說過Spring的兩大特征,一個(gè)是 IOC ,一個(gè)是 AOP ,我們現(xiàn)在要學(xué)習(xí)的就是這個(gè)AOP。 ??AOP: 面向切面編程 ,一種編程范式,指導(dǎo)開發(fā)者如何組織程序結(jié)構(gòu)。 ??作用:在不驚動(dòng)原始設(shè)計(jì)的基礎(chǔ)上為其進(jìn)行 功能增強(qiáng) 。 ??首先我們先

    2024年01月25日
    瀏覽(26)
  • Spring AOP:面向切面編程在實(shí)際項(xiàng)目中的應(yīng)用

    Spring AOP:面向切面編程在實(shí)際項(xiàng)目中的應(yīng)用

    ???? 博主貓頭虎(????)帶您 Go to New World??? ?? 博客首頁 ——????貓頭虎的博客?? ?? 《面試題大全專欄》 ?? 文章圖文并茂??生動(dòng)形象??簡(jiǎn)單易學(xué)!歡迎大家來踩踩~?? ?? 《IDEA開發(fā)秘籍專欄》 ?? 學(xué)會(huì)IDEA常用操作,工作效率翻倍~?? ?? 《100天精通Golang(基礎(chǔ)

    2024年02月09日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包