您的位置:  首頁 > 技術 > java語言 > 正文

《Spring 手擼專欄》第 9 章:虎行有雨,定義標記類型Aware接口,實現感知容器對象

2021-07-05 23:16 OSCHINA 小傅哥 次閱讀 條評論

目錄


  • 一、前言

  • 二、目標

  • 三、設計

  • 四、實現

    • 1. 工程結構

    • 2. 定義標記接口

    • 3. 容器感知類

    • 4. 包裝處理器(ApplicationContextAwareProcessor)

    • 5. 注冊 BeanPostProcessor

    • 6. 感知調用操作

  • 五、測試

    • 1. 事先準備

    • 2. 配置文件

    • 3. 單元測試

  • 六、總結

  • 七、系列推薦


?

一、前言

同事寫的代碼,我竟絲毫看不懂!

大佬的代碼,就像“賴蛤蟆泡青蛙,長的丑玩的花”:一個類實現了多個接口、繼承的類又繼承了其他類、接口還可以和接口繼承、實現接口的抽象類再由類實現抽象類方法、類A繼承的類B實現了類A實現的接口C,等等。

看上去復雜又難懂的代碼,卻又能一次次滿足需求的高效迭代和順利擴展,而像螺絲釘一樣搬磚的你,只是在大佬寫的代碼里,完成某個接口下的一小塊功能,甚至寫完了也不知道怎么就被調用運行了,整個過程像看 Spring 源碼一樣神奇,跳來跳去的摸不著頭緒!

其實這主要是因為你的代碼是否運用了設計模式,當然設計模式也沒那么神奇,就像你們兩家都是120平米的房子,他家有三室兩廳一廚一衛,南北通透,全陽采光。但你家就不一樣了,你家是鍋碗瓢盆、衛浴馬桶、沙發茶幾還有那1.8的雙人床,在120平米的房子里敞開了放,沒有動靜隔離,也沒有干濕分離,純自由發揮。所以你的代碼看上去就亂的很!

?

二、目標

目前已實現的 Spring 框架,在 Bean 操作上能提供出的能力,包括:Bean 對象的定義和注冊,以及在操作 Bean 對象過程中執行的,BeanFactoryPostProcessor、BeanPostProcessor、InitializingBean、DisposableBean,以及在 XML 新增的一些配置處理,讓我們可以 Bean 對象有更強的操作性。

那么,如果我們想獲得 Spring 框架提供的 BeanFactory、ApplicationContext、BeanClassLoader等這些能力做一些擴展框架的使用時該怎么操作呢。所以我們本章節希望在 Spring 框架中提供一種能感知容器操作的接口,如果誰實現了這樣的一個接口,就可以獲取接口入參中的各類能力。

?

三、設計

如果說我希望拿到 Spring 框架中一些提供的資源,那么首先需要考慮以一個什么方式去獲取,之后你定義出來的獲取方式,在 Spring 框架中該怎么去承接,實現了這兩項內容,就可以擴展出你需要的一些屬于 Spring 框架本身的能力了。

在關于 Bean 對象實例化階段我們操作過一些額外定義、屬性、初始化和銷毀的操作,其實我們如果像獲取 Spring 一些如 BeanFactory、ApplicationContext 時,也可以通過此類方式進行實現。那么我們需要定義一個標記性的接口,這個接口不需要有方法,它只起到標記作用就可以,而具體的功能由繼承此接口的其他功能性接口定義具體方法,最終這個接口就可以通過 instanceof 進行判斷和調用了。整體設計結構如下圖:

  • 定義接口 Aware,在 Spring 框架中它是一種感知標記性接口,具體的子類定義和實現能感知容器中的相關對象。 ? ? 也就是通過這個橋梁,向具體的實現類中提供容器服務 ? ?
  • 繼承 Aware 的接口包括:BeanFactoryAware、BeanClassLoaderAware、BeanNameAware和ApplicationContextAware,當然在 Spring 源碼中還有一些其他關于注解的,不過目前我們還是用不到。
  • 在具體的接口實現過程中你可以看到,一部分( ? ? BeanFactoryAware、BeanClassLoaderAware、BeanNameAware)在 factory 的 support 文件夾下,另外 ApplicationContextAware 是在 context 的 support 中,這是因為不同的內容獲取需要在不同的包下提供。所以,在 AbstractApplicationContext 的具體實現中會用到向 beanFactory 添加 BeanPostProcessor 內容的 ? ? ApplicationContextAwareProcessor 操作,最后由 AbstractAutowireCapableBeanFactory 創建 createBean 時處理相應的調用操作。 ? ? 關于 applyBeanPostProcessorsBeforeInitialization 已經在前面章節中實現過,如果忘記可以往前翻翻 ? ?
?

四、實現

?

1. 工程結構

small-spring-step-08
└──?src
????├──?main
????│???└──?java
????│???????└──?cn.bugstack.springframework
????│???????????├──?beans
????│???????????│???├──?factory
????│???????????│???│???├──?factory
????│???????????│???│???│???├──?AutowireCapableBeanFactory.java
????│???????????│???│???│???├──?BeanDefinition.java
????│???????????│???│???│???├──?BeanFactoryPostProcessor.java
????│???????????│???│???│???├──?BeanPostProcessor.java
????│???????????│???│???│???├──?BeanReference.java
????│???????????│???│???│???├──?ConfigurableBeanFactory.java
????│???????????│???│???│???└──?SingletonBeanRegistry.java
????│???????????│???│???├──?support
????│???????????│???│???│???├──?AbstractAutowireCapableBeanFactory.java
????│???????????│???│???│???├──?AbstractBeanDefinitionReader.java
????│???????????│???│???│???├──?AbstractBeanFactory.java
????│???????????│???│???│???├──?BeanDefinitionReader.java
????│???????????│???│???│???├──?BeanDefinitionRegistry.java
????│???????????│???│???│???├──?CglibSubclassingInstantiationStrategy.java
????│???????????│???│???│???├──?DefaultListableBeanFactory.java
????│???????????│???│???│???├──?DefaultSingletonBeanRegistry.java
????│???????????│???│???│???├──?DisposableBeanAdapter.java
????│???????????│???│???│???├──?InstantiationStrategy.java
????│???????????│???│???│???└──?SimpleInstantiationStrategy.java??
????│???????????│???│???├──?support
????│???????????│???│???│???└──?XmlBeanDefinitionReader.java
????│???????????│???│???├──?Aware.java
????│???????????│???│???├──?BeanClassLoaderAware.java
????│???????????│???│???├──?BeanFactory.java
????│???????????│???│???├──?BeanFactoryAware.java
????│???????????│???│???├──?BeanNameAware.java
????│???????????│???│???├──?ConfigurableListableBeanFactory.java
????│???????????│???│???├──?DisposableBean.java
????│???????????│???│???├──?HierarchicalBeanFactory.java
????│???????????│???│???├──?InitializingBean.java
????│???????????│???│???└──?ListableBeanFactory.java
????│???????????│???├──?BeansException.java
????│???????????│???├──?PropertyValue.java
????│???????????│???└──?PropertyValues.java?
????│???????????├──?context
????│???????????│???├──?support
????│???????????│???│???├──?AbstractApplicationContext.java?
????│???????????│???│???├──?AbstractRefreshableApplicationContext.java?
????│???????????│???│???├──?AbstractXmlApplicationContext.java?
????│???????????│???│???├──?ApplicationContextAwareProcessor.java?
????│???????????│???│???└──?ClassPathXmlApplicationContext.java?
????│???????????│???├──?ApplicationContext.java?
????│???????????│???├──?ApplicationContextAware.java?
????│???????????│???└──?ConfigurableApplicationContext.java
????│???????????├──?core.io
????│???????????│???├──?ClassPathResource.java?
????│???????????│???├──?DefaultResourceLoader.java?
????│???????????│???├──?FileSystemResource.java?
????│???????????│???├──?Resource.java?
????│???????????│???├──?ResourceLoader.java?
????│???????????│???└──?UrlResource.java
????│???????????└──?utils
????│???????????????└──?ClassUtils.java
????└──?test
????????└──?java
????????????└──?cn.bugstack.springframework.test
????????????????├──?bean
????????????????│???├──?UserDao.java
????????????????│???└──?UserService.java
????????????????└──?ApiTest.java
?

工程源碼公眾號「bugstack蟲洞?!?#xff0c;回復:Spring 專欄,獲取完整源碼

Spring 感知接口的設計和實現類關系,如圖 9-2

圖 9-2
  • 以上整個類關系就是關于 Aware 感知的定義和對容器感知的實現。
  • Aware 有四個繼承的接口,其他這些接口的繼承都是為了繼承一個標記,有了標記的存在更方便類的操作和具體判斷實現。
  • 另外由于 ApplicationContext 并不是在 AbstractAutowireCapableBeanFactory 中 createBean 方法下的內容,所以需要像容器中注冊 ? ? addBeanPostProcessor ,再由 ?createBean ?統一調用 applyBeanPostProcessorsBeforeInitialization 時進行操作。
?

2. 定義標記接口

cn.bugstack.springframework.beans.factory.Aware

/**
?*?Marker?superinterface?indicating?that?a?bean?is?eligible?to?be
?*?notified?by?the?Spring?container?of?a?particular?framework?object
?*?through?a?callback-style?method.??Actual?method?signature?is
?*?determined?by?individual?subinterfaces,?but?should?typically
?*?consist?of?just?one?void-returning?method?that?accepts?a?single
?*?argument.
?*
?*?標記類接口,實現該接口可以被Spring容器感知
?*
?*/

public?interface?Aware?{
}
?
  • 在 Spring 中有特別多類似這樣的標記接口的設計方式,它們的存在就像是一種標簽一樣,可以方便統一摘取出屬于此類接口的實現類,通常會有 instanceof 一起判斷使用。
?

3. 容器感知類

?

3.1 BeanFactoryAware

cn.bugstack.springframework.beans.factory.BeanFactoryAware

public?interface?BeanFactoryAware?extends?Aware?{

???void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException;

}
?
  • Interface to be implemented by beans that wish to be aware of their owning {@link BeanFactory}.
  • 實現此接口,既能感知到所屬的 BeanFactory
?

3.2 BeanClassLoaderAware

cn.bugstack.springframework.beans.factory.BeanClassLoaderAware

public?interface?BeanClassLoaderAware?extends?Aware{

????void?setBeanClassLoader(ClassLoader?classLoader);

}
?
  • Callback that allows a bean to be aware of the bean{@link ClassLoader class loader}; that is, the class loader used by the present bean factory to load bean classes.
  • 實現此接口,既能感知到所屬的 ClassLoader
?

3.3 BeanNameAware

cn.bugstack.springframework.beans.factory.BeanNameAware

public?interface?BeanNameAware?extends?Aware?{

????void?setBeanName(String?name);

}
?
  • Interface to be implemented by beans that want to be aware of their bean name in a bean factory.
  • 實現此接口,既能感知到所屬的 BeanName
?

3.4 ApplicationContextAware

cn.bugstack.springframework.context.ApplicationContextAware

public?interface?ApplicationContextAware?extends?Aware?{

????void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException;

}
?
  • Interface to be implemented by any object that wishes to be notifiedof the {@link ApplicationContext} that it runs in.
  • 實現此接口,既能感知到所屬的 ApplicationContext
?

4. 包裝處理器(ApplicationContextAwareProcessor)

cn.bugstack.springframework.context.support.ApplicationContextAwareProcessor

public?class?ApplicationContextAwareProcessor?implements?BeanPostProcessor?{

????private?final?ApplicationContext?applicationContext;

????public?ApplicationContextAwareProcessor(ApplicationContext?applicationContext)?{
????????this.applicationContext?=?applicationContext;
????}

????@Override
????public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????if?(bean?instanceof?ApplicationContextAware){
????????????((ApplicationContextAware)?bean).setApplicationContext(applicationContext);
????????}
????????return?bean;
????}

????@Override
????public?Object?postProcessAfterInitialization(Object?bean,?String?beanName)?throws?BeansException?{
????????return?bean;
????}

}
?
  • 由于 ApplicationContext 的獲取并不能直接在創建 Bean 時候就可以拿到,所以需要在 refresh 操作時,把 ApplicationContext 寫入到一個包裝的 BeanPostProcessor 中去,再由 AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization 方法調用。
?

5. 注冊 BeanPostProcessor

cn.bugstack.springframework.context.support.AbstractApplicationContext

public?abstract?class?AbstractApplicationContext?extends?DefaultResourceLoader?implements?ConfigurableApplicationContext?{

????@Override
????public?void?refresh()?throws?BeansException?{
????????//?1.?創建?BeanFactory,并加載?BeanDefinition
????????refreshBeanFactory();

????????//?2.?獲取?BeanFactory
????????ConfigurableListableBeanFactory?beanFactory?=?getBeanFactory();

????????//?3.?添加?ApplicationContextAwareProcessor,讓繼承自?ApplicationContextAware?的?Bean?對象都能感知所屬的?ApplicationContext
????????beanFactory.addBeanPostProcessor(new?ApplicationContextAwareProcessor(this));

????????//?4.?在?Bean?實例化之前,執行?BeanFactoryPostProcessor?(Invoke?factory?processors?registered?as?beans?in?the?context.)
????????invokeBeanFactoryPostProcessors(beanFactory);

????????//?5.?BeanPostProcessor?需要提前于其他?Bean?對象實例化之前執行注冊操作
????????registerBeanPostProcessors(beanFactory);

????????//?6.?提前實例化單例Bean對象
????????beanFactory.preInstantiateSingletons();
????}
????
??//?...???
}????
?
  • refresh() 方法就是整個 Spring 容器的操作過程,與上一章節對比,本次新增加了關于 addBeanPostProcessor 的操作。
  • 添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對象都能感知所屬的 ApplicationContext。
?

6. 感知調用操作

cn.bugstack.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

public?abstract?class?AbstractAutowireCapableBeanFactory?extends?AbstractBeanFactory?implements?AutowireCapableBeanFactory?{

????private?InstantiationStrategy?instantiationStrategy?=?new?CglibSubclassingInstantiationStrategy();

????@Override
????protected?Object?createBean(String?beanName,?BeanDefinition?beanDefinition,?Object[]?args)?throws?BeansException?{
????????Object?bean?=?null;
????????try?{
????????????bean?=?createBeanInstance(beanDefinition,?beanName,?args);
????????????//?給?Bean?填充屬性
????????????applyPropertyValues(beanName,?bean,?beanDefinition);
????????????//?執行?Bean?的初始化方法和?BeanPostProcessor?的前置和后置處理方法
????????????bean?=?initializeBean(beanName,?bean,?beanDefinition);
????????}?catch?(Exception?e)?{
????????????throw?new?BeansException("Instantiation?of?bean?failed",?e);
????????}

????????//?注冊實現了?DisposableBean?接口的?Bean?對象
????????registerDisposableBeanIfNecessary(beanName,?bean,?beanDefinition);

????????addSingleton(beanName,?bean);
????????return?bean;
????}

????private?Object?initializeBean(String?beanName,?Object?bean,?BeanDefinition?beanDefinition)?{

????????//?invokeAwareMethods
????????if?(bean?instanceof?Aware)?{
????????????if?(bean?instanceof?BeanFactoryAware)?{
????????????????((BeanFactoryAware)?bean).setBeanFactory(this);
????????????}
????????????if?(bean?instanceof?BeanClassLoaderAware){
????????????????((BeanClassLoaderAware)?bean).setBeanClassLoader(getBeanClassLoader());
????????????}
????????????if?(bean?instanceof?BeanNameAware)?{
????????????????((BeanNameAware)?bean).setBeanName(beanName);
????????????}
????????}

????????//?1.?執行?BeanPostProcessor?Before?處理
????????Object?wrappedBean?=?applyBeanPostProcessorsBeforeInitialization(bean,?beanName);

????????//?執行?Bean?對象的初始化方法
????????try?{
????????????invokeInitMethods(beanName,?wrappedBean,?beanDefinition);
????????}?catch?(Exception?e)?{
????????????throw?new?BeansException("Invocation?of?init?method?of?bean["?+?beanName?+?"]?failed",?e);
????????}

????????//?2.?執行?BeanPostProcessor?After?處理
????????wrappedBean?=?applyBeanPostProcessorsAfterInitialization(bean,?beanName);
????????return?wrappedBean;
????}



????@Override
????public?Object?applyBeanPostProcessorsBeforeInitialization(Object?existingBean,?String?beanName)?throws?BeansException?{
????????Object?result?=?existingBean;
????????for?(BeanPostProcessor?processor?:?getBeanPostProcessors())?{
????????????Object?current?=?processor.postProcessBeforeInitialization(result,?beanName);
????????????if?(null?==?current)?return?result;
????????????result?=?current;
????????}
????????return?result;
????}

????@Override
????public?Object?applyBeanPostProcessorsAfterInitialization(Object?existingBean,?String?beanName)?throws?BeansException?{
????????Object?result?=?existingBean;
????????for?(BeanPostProcessor?processor?:?getBeanPostProcessors())?{
????????????Object?current?=?processor.postProcessAfterInitialization(result,?beanName);
????????????if?(null?==?current)?return?result;
????????????result?=?current;
????????}
????????return?result;
????}

}
?
  • 這里我們去掉了一些類的內容,只保留關于本次 Aware 感知接口的操作。
  • 首先在 initializeBean 中,通過判斷 ? ? bean instanceof Aware,調用了三個接口方法, ? ? BeanFactoryAware.setBeanFactory(this)、 ? ? BeanClassLoaderAware.setBeanClassLoader(getBeanClassLoader())、 ? ? BeanNameAware.setBeanName(beanName),這樣就能通知到已經實現了此接口的類。
  • 另外我們還向 BeanPostProcessor 中添加了 ? ? ApplicationContextAwareProcessor,此時在這個方法中也會被調用到具體的類實現,得到一個 ApplicationContex 屬性。
?

五、測試

?

1. 事先準備

cn.bugstack.springframework.test.bean.UserDao

public?class?UserDao?{

????private?static?Map<String,?String>?hashMap?=?new?HashMap<>();

????public?void?initDataMethod(){
????????System.out.println("執行:init-method");
????????hashMap.put("10001",?"小傅哥");
????????hashMap.put("10002",?"八杯水");
????????hashMap.put("10003",?"阿毛");
????}

????public?void?destroyDataMethod(){
????????System.out.println("執行:destroy-method");
????????hashMap.clear();
????}

????public?String?queryUserName(String?uId)?{
????????return?hashMap.get(uId);
????}

}
?

cn.bugstack.springframework.test.bean.UserService

public?class?UserService?implements?BeanNameAware,?BeanClassLoaderAware,?ApplicationContextAware,?BeanFactoryAware?{

????private?ApplicationContext?applicationContext;
????private?BeanFactory?beanFactory;

????private?String?uId;
????private?String?company;
????private?String?location;
????private?UserDao?userDao;

????@Override
????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
????????this.beanFactory?=?beanFactory;
????}

????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????this.applicationContext?=?applicationContext;
????}

????@Override
????public?void?setBeanName(String?name)?{
????????System.out.println("Bean Name is:"?+?name);
????}

????@Override
????public?void?setBeanClassLoader(ClassLoader?classLoader)?{
????????System.out.println("ClassLoader:"?+?classLoader);
????}

????//?...get/set
}
?
  • UserDao 本次并沒有什么改變,還是提供了關于初始化的方法,并在 Spring.xml 中提供 init-method、destroy-method 配置信息。
  • UserService 新增加,BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware,四個感知的實現類,并在類中實現相應的接口方法。
?

2. 配置文件

基礎配置,無BeanFactoryPostProcessor、BeanPostProcessor,實現類

<?xml?version="1.0"?encoding="UTF-8"?>
<beans>

????<bean?id="userDao"?class="cn.bugstack.springframework.test.bean.UserDao"?init-method="initDataMethod"?destroy-method="destroyDataMethod"/>

????<bean?id="userService"?class="cn.bugstack.springframework.test.bean.UserService">
????????<property?name="uId"?value="10001"/>
????????<property?name="company"?value="騰訊"/>
????????<property?name="location"?value="深圳"/>
????????<property?name="userDao"?ref="userDao"/>
????</bean>

</beans>
?
  • 本章節中并沒有額外新增加配置信息,與上一章節內容相同。
?

3. 單元測試

@Test
public?void?test_xml()?{
????//?1.初始化?BeanFactory
????ClassPathXmlApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext("classpath:spring.xml");
????applicationContext.registerShutdownHook();??????

????//?2.?獲取Bean對象調用方法
????UserService?userService?=?applicationContext.getBean("userService",?UserService.class);
????String?result?=?userService.queryUserInfo();
????System.out.println("測試結果:"?+?result);
????System.out.println("ApplicationContextAware:"+userService.getApplicationContext());
????System.out.println("BeanFactoryAware:"+userService.getBeanFactory());
}
?
  • 測試方法中主要是添加了一寫關于新增 Aware 實現的調用,其他不需要調用的也打印了相應的日志信息,可以在測試結果中看到。

測試結果

執行:init-method
ClassLoader:sun.misc.Launcher$AppClassLoader@14dad5dc
Bean Name is:userService
測試結果:小傅哥,騰訊,深圳
ApplicationContextAware:cn.bugstack.springframework.context.support.ClassPathXmlApplicationContext@5ba23b66
BeanFactoryAware:cn.bugstack.springframework.beans.factory.support.DefaultListableBeanFactory@2ff4f00f
執行:destroy-method



Process?finished?with?exit?code?0
?
  • 從測試結果可以看到,本章節新增加的感知接口對應的具體實現(BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware),已經可以如期輸出結果了。
?

六、總結

  • 目前關于 Spring 框架的實現中,某些功能點已經越來趨向于完整,尤其是 Bean 對象的生命周期,已經有了很多的體現。整體總結如下圖:


?

  • 本章節關于 Aware 的感知接口的四個繼承接口 BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware 的實現,又擴展了 Spring 的功能。如果你有做過關于 Spring 中間件的開發那么一定會大量用到這些類,現在你不只是用過,而且還知道他們都是什么時候觸達的,在以后想排查類的實例化順序也可以有一個清晰的思路了。

  • 每一章節內容的實現都是在以設計模式為核心的結構上填充各項模塊的功能,單純的操作編寫代碼并不會有太多收獲,一定是要理解為什么這么設計,這么設計的好處是什么,怎么就那么多接口和抽象類的應用,這些才是 Spring 框架學習的核心所在。

  • 0
    感動
  • 0
    路過
  • 0
    高興
  • 0
    難過
  • 0
    搞笑
  • 0
    無聊
  • 0
    憤怒
  • 0
    同情
熱度排行
友情鏈接
18禁高潮出水呻吟娇喘mp3,日本熟妇乱人伦A片免费高清,成人午夜精品无码区,狠狠色噜噜色狠狠狠综合久久,麻豆一区二区99久久久久,年轻的妈妈4,少妇被又大又粗又爽毛片,护士张开腿让我爽了一夜,男男互攻互受h啪肉np文,你好神枪手电视剧免费观看啊,97人妻一区二区精品免费,久久久婷婷五月亚洲97号色,freegaysexvideos男男中国,国产精品国产三级国av麻豆,国产精品又黄又爽又色无遮挡网站,亚洲av无码一区二区三区网站,亚洲国产精品久久久久蜜桃,国产真人无码作爱视频免费,国产成人精品亚洲一区二区三区,亚洲欧洲日产最新,老司机带带我精彩免费,国产成人久久精品激情,日本最新av免费一区二区三区,边摸边吃奶又黄又激烈视频
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>