Java的注解機(jī)制-Spring自動(dòng)裝配的實(shí)現(xiàn)原理_第1頁
Java的注解機(jī)制-Spring自動(dòng)裝配的實(shí)現(xiàn)原理_第2頁
Java的注解機(jī)制-Spring自動(dòng)裝配的實(shí)現(xiàn)原理_第3頁
Java的注解機(jī)制-Spring自動(dòng)裝配的實(shí)現(xiàn)原理_第4頁
Java的注解機(jī)制-Spring自動(dòng)裝配的實(shí)現(xiàn)原理_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Java的注解機(jī)制——Sprinjg動(dòng)裝配的實(shí)現(xiàn)原理阿何的程序人生J加入了對注解機(jī)制的支持,實(shí)際上我學(xué)習(xí)Java的時(shí)候就已經(jīng)使用J了,而且除了vrri和Spprarn后者還是給生成的之外沒接觸過其他的。進(jìn)入公司前的面試,技術(shù)人員就問了我關(guān)于注解的問題,我就說可以生成手冊現(xiàn)在想起來真囧,注釋和注解被我搞得完全一樣了。使用注解主要是在需要使用Spring匡架的時(shí)候,特別是使用Spring。因?yàn)檫@時(shí)我們會發(fā)現(xiàn)它的強(qiáng)大之處:預(yù)處理。注解實(shí)際上相當(dāng)于一種標(biāo)記,它允許你在運(yùn)行時(shí)源碼、文檔、類文件我們就不討論了動(dòng)態(tài)地對擁有該標(biāo)記的成員進(jìn)行操作。實(shí)現(xiàn)注解需要三個(gè)條件我們討論的是類似于Spring^動(dòng)裝配的高級應(yīng)用:注解聲明、使用注解的元素、操作使用注解元素的代碼。首先是注解聲明,注解也是一種類型,我們要定義的話也需要編寫代碼,如下:packageannotation;imprtjava.langannotation.ElementTimportjava.lang.annotation.Retentionimportjava.langannotation.Retentionimportjava.lang.annotation.Target;自定義注解,用來配置方法*@authorJohness@Retention(Retnin表示注i解在運(yùn)行時(shí)依然存在argn表示注解可以被使用于方法上piinraSainnainSringparaa表示我的注解需要一個(gè)參數(shù)名為paraa默認(rèn)值為n然后是使用我們注解的元素:paagnprannainSainnain要使用Sainn的元素所在類由于我們定義了只有方法才能使用我們的注解,我們就使用多個(gè)方法來進(jìn)行測試pilassSayHiEmlement{普通的方/法/publicvoSysidSayHiDefault(Stringnamt.println("Hi,"+na使用注解并傳入?yún)?shù)的方法ionn("nana@SayHiAnnotation(paramVapublicvoidSayHiAnnotaionn("nanaSystem.out.print使用注解/并/使用默認(rèn)參數(shù)的方法@SayHiAnnotationpublicvoidSayHiAnnotationDefault(StringnaSystem.out.println("Hi,"+name:;最后,是我們的操作方法值得一提的是雖然有一定的規(guī)范,但您大可不必去浪費(fèi)精力,您只需要保證您的操作代碼在您希望的時(shí)候執(zhí)行即可::packageMain;23importjava.lang.reflect.InvocationTargetException;4importjava.lang.reflect.Method;56importelement.SayHiEmlement;7importannotation.SayHiAnnotation;8publicclassAnnotionOperator{publicstaticvoidmain(String[]args)throwsIllegalAccessException,IllegalArgumentException,InvocationTargetException,ClassNotFoundException{SayHiEmlementelement=newSayHiEmlement();//初始化一個(gè)實(shí)例,用于方法調(diào)用Method]]methods=SayHiEmlement.class.getDeclaredMethods();//獲得所有方法13for(Methodmethod:methods){SayHiAnnotationannotationTmp=null;if((annotationTmp=method.getAnnotation(SayHiAnnotation.class))!=null)//檢測是否使用了我們的注解method.invoke(element,annotationTmp.paramValue());//如果使用了我們的注解,我們就把注解里的"paramValue"參數(shù)值作為方法參數(shù)來調(diào)用方法elsemethod.invoke(element,"Rose");//如果沒有使用我們的注解,我們就需要使用普通的方式來調(diào)用方法了}}}結(jié)果為:Hi,JackHi,johnessHi,Rose可以看到,注解是進(jìn)行預(yù)處理的很好方式(這里的預(yù)處理和編譯原理有區(qū)別)!接下來我們看看Spring是如何使用注解機(jī)制完成自動(dòng)裝配的:首先是為了讓Spring為我們自動(dòng)裝配要進(jìn)行的操作,無外乎兩種:繼承org.springframework.web.context.support.SpringBeanAutowiringSupport類或者添加@Component/@Controller等注解并(只是使用注解方式需要)在Spring配置文件里聲明context:component-scan元素。我說說繼承方式是如何實(shí)現(xiàn)自動(dòng)裝配的,我們打開Spring源代碼查看SpringBeanAutowiringSupport類。我們會發(fā)現(xiàn)以下語句:publicSpringBeanAutowiringSupport(){processInjectionBasedOnCurrentContext(this);}眾所周知,Java實(shí)例構(gòu)造時(shí)會調(diào)用默認(rèn)父類無參構(gòu)造方法,Spring正是利用了這一點(diǎn),讓"操作元素的代碼"得以執(zhí)行!(我看到第一眼就震驚了!真是奇思妙想啊。果然,咼手都要善于用Java來用Java)后面的我就不就不多說了,不過還是要糾正一些人的觀點(diǎn):說使用注解的自動(dòng)裝配來完成注入也需better。這明顯是錯(cuò)誤的嘛!我們看Spring注解裝配(繼承方式)的方法調(diào)用順序:org.springframework.web.context.support.SpringBeanAutowiringSupport#SpringBeanAutowiringSupport=>org.springframework.web.context.support.SpringBeanAutowiringSupport#processInjectionBasedOnCurrentContext=>org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#processInjection=>org.springframework?beans.factory.annotation.lnjectionMetadata#Injectioi繼承,方法重寫)。最后看看Injection方法的方法體:1/***Eitherthisor{@link#getResourceToInject}needstobeoverridden.*/protectedvoidinject(Objecttarget,StringrequestingBeanName,PropertyValuespvs)throwsThrowable{if(this.isField){Fieldfield=(Field)this.member;ReflectionUtils.makeAccessible(field);field.set(target,getResourceToInject(target,requestingBeanName));}else{if(checkPropertySkipping(pvs)){return;}try{Methodmethod=(Method)this.member;ReflectionUtils.makeAccessible(method);method.invoke(target,getResourceToInject(target,requestingBeanName));}catch(InvocationTargetExceptionex){throwex.getTargetException();}}}雖然不完全,但可以基本判定此種自動(dòng)裝配是使用了ava放射機(jī)制。分類:2011-05-0615:267573人閱讀(11)本文將向你介紹J2SE5.0中的新特性之一:注解。本文將從什么是注解;J2SE5.0中預(yù)定義的注解;如何自定義注解;如何對注解進(jìn)行注解以及如何在程序中讀取注解5個(gè)方面進(jìn)行討論。―、什么是注解說起注解,得先提一提什么是元數(shù)據(jù)(metadata)。所謂元數(shù)據(jù)就是數(shù)據(jù)的數(shù)據(jù)。也就是說,元數(shù)據(jù)是描述數(shù)據(jù)的。就象數(shù)據(jù)表中的字段一樣,每個(gè)字段描述了這個(gè)字段下的數(shù)據(jù)的含義。而J2SE5.0中提供的注解就是java源代碼的元數(shù)據(jù),也就是說注解是描述ava源代碼的。在J2SE5.0中可以自定義注解。使用時(shí)在@后面跟注解的名字。二、J2SE5.0中預(yù)定義的注解在J2SE5.0的java.lang包中預(yù)定義了三個(gè)注解。它們是Override、Deprecated和SuppressWarnings。下面分別解解它們的含義。Override這個(gè)注解的作用是標(biāo)識某一個(gè)方法是否覆蓋了它的父類的方法。那么為什么要標(biāo)識呢?讓我們來看看如果不用Override標(biāo)識會發(fā)生什么事情。假設(shè)有兩個(gè)類Class1和ParentClass1,用Class1中的myMethod1方法覆蓋ParentClass1中的myMethod1方法。classParentClass1{publicvoidmyMethod1(){}}classClass1extendsParentClass1{publicvoidmyMethod2(){}}建立Class1的實(shí)例,并且調(diào)用myMethod1方法ParentClass1c1=newClass1();c1.myMethod1();以上的代碼可以正常編譯通過和運(yùn)行。但是在寫Class1的代碼時(shí),誤將myMethod1寫成了myMethod2,然而在調(diào)用時(shí),myMethod1并未被覆蓋。因此,c1.myMethod1()調(diào)用的還是ParentClassl的myMethodl方法。更不幸的是,程序員并未意識到這一點(diǎn)。因此,這可能會產(chǎn)生bug。如果我們使用Override來修飾Class1中的myMethod1方法,當(dāng)myMethod1被誤寫成別的方法時(shí),編譯器就會報(bào)錯(cuò)。因此,就可以避免這類錯(cuò)誤。classClass1extendsParentClass1{@Override/編譯器產(chǎn)生一個(gè)錯(cuò)誤publicvoidmyMethod2(){}}以上代碼編譯不能通過,被Override注解的方法必須在父類中存在同樣的方法程序才能編譯通過。也就是說只有下面的代碼才能正確編譯。classClass1extendsParentClass1{@OverridepublicvoidmyMethod1(){}}Deprecated這個(gè)注解是一個(gè)標(biāo)記注解。所謂標(biāo)記注解,就是在源程序中加入這個(gè)標(biāo)記后,并不影響程序的編譯,但有時(shí)編譯器會顯示一些警告信息。那么Deprecated注解是什么意思呢?如果你經(jīng)常使用eclipse等IDE編寫java程序時(shí),可能會經(jīng)常在屬性或方法提示中看到這個(gè)詞。如果某個(gè)類成員的提示中出現(xiàn)了個(gè)詞,就表示這個(gè)并不建議使用這個(gè)類成員。因?yàn)檫@個(gè)類成員在未來的JDK版本中可能被刪除。之所以在現(xiàn)在還保留,是因?yàn)榻o那些已經(jīng)使用了這些類成員的程序一個(gè)緩沖期。如果現(xiàn)在就去了,那么這些程序就無法在新的編譯器中編譯了。說到這,可能你已經(jīng)猜出來了。Deprecated注解一定和這些類成員有關(guān)。說得對!使用Deprecated標(biāo)注一個(gè)類成員后,這個(gè)類成員在顯示上就會有一些變化。在eclipse中非常明顯。讓我們看看圖1有哪些變化。從上圖可以看出,有三個(gè)地方發(fā)生的變化。紅色框里面的是變化的部分。方法定義處方法引用處顯示的成員列表中發(fā)生這些變化并不會影響編譯,只是提醒一下程序員,這個(gè)方法以后是要被刪除的,最好別用。Deprecated注解還有一個(gè)作用。就是如果一個(gè)類從另外一個(gè)類繼承,并且override被繼承類的Deprecated方法,在編譯時(shí)將會出現(xiàn)一個(gè)警告。^口test.java的內(nèi)容如下:classClass1{@DeprecatedpublicvoidmyMethod(){}}classClass2extendsClass1{publicvoidmyMethod(){}}運(yùn)行javactest.java出現(xiàn)如下警告:注意:test.java使用或覆蓋了已過時(shí)的API。注意:要了解詳細(xì)信息,請使用-Xlint:deprecation重新編譯使用-Xlint:deprecation顯示更詳細(xì)的警告信息:test.java:4:警告:[deprecation]Class1中的myMethod()已過時(shí)publicvoidmyMethod()1警告這些警告并不會影響編譯,只是提醒你一下盡量不要用myMethod方法。SuppressWarnings這個(gè)世界的事物總是成對出現(xiàn)。即然有使編譯器產(chǎn)生警告信息的,那么就有抑制編譯器產(chǎn)生警告信息的SuppressWarnings注解就是為了這樣一個(gè)目的而存在的。讓我們先看一看如下的代碼。publicvoidmyMethod(){ListwordList=newArrayList();wordList.add("foo");}這是一個(gè)類中的方法。編譯它,將會得到如下的警告。注意:Testannotation.java使用了未經(jīng)檢查或不安全的操作注意:要了解詳細(xì)信息,請使用-Xlint:unchecked重新編譯。這兩行警告信息表示List類必須使用范型才是安全的,才可以進(jìn)行類型檢查。如果想不顯示這個(gè)警告信息有兩種方法。一個(gè)是將這個(gè)方法進(jìn)行如下改寫:publicvoidmyMethod(){List<String>wordList=newArrayList<String>();wordList.add("foo");}另外一種方法就是使用@SuppressWarnings。@SuppressWarnings(value={"unchecked"})publicvoidmyMethod(){ListwordList=newArrayList();wordList.add("foo");}要注意的是SuppressWarnings和前兩個(gè)注解不一樣。這個(gè)注解有一個(gè)屬性。當(dāng)然,還可以抑制其它警告,女Q@SuppressWarnings(value={"unchecked","fallthrough"})三、如何自定義注解注解的強(qiáng)大之處是它不僅可以使java程序變成自描述的,而且允許程序員自定義注解。注解的定義和接口差不多,只是在nterface前面多了一個(gè)“@”。public@interfaceMyAnnotation{}上面的代碼是一個(gè)最簡單的注解。這個(gè)注解沒有屬性。也可以理解為是一個(gè)標(biāo)記注解。就象Serializable接口一樣是一個(gè)標(biāo)記接口,里面未定義任何方法。當(dāng)然,也可以定義而有屬性的注解。public@interfaceMyAnnotation{Stringvalue();}可以按如下格式使用MyAnnotation@MyAnnotation(“abc”)publicvoidmyMethod(){}看了上面的代碼,大家可能有一個(gè)疑問。怎么沒有使用zalue,而直接就寫”abc”了。那么”abc”到底傳給誰了。其實(shí)這里有一個(gè)約定。如果沒有寫屬性名的值,而這個(gè)注解又有value屬性,就將這個(gè)值賦給value屬性,如果沒有,就出現(xiàn)編譯錯(cuò)誤。除了可以省略屬性名,還可以省略屬性值。這就是默認(rèn)值。public@interfaceMyAnnotation{publicStringmyMethod()default"xyz";可以直接使用MyAnnotation@MyAnnotation//使用默認(rèn)值xyzpublicvoidmyMethod(){}也可以這樣使用@MyAnnotation(myMethod=”abc”)publicvoidmyMethod(){}如果要使用多個(gè)屬性的話??梢詤⒖既缦麓a。public@interfaceMyAnnotation{publicenumMyEnum{A,B,C}publicMyEnumvalue1();publicStringvalue2();}@MyAnnotation(value1=MyAnnotation.MyEnum.A,value2=“xyz”)publicvoidmyMethod(){}這一節(jié)討論了如何自定義注解。那么定義注解有什么用呢?有什么方法對注解進(jìn)行限制呢?我們能從程序中得到注解嗎?這些疑問都可以從下面的內(nèi)容找到答案。四、如何對注解進(jìn)行注解這一節(jié)的題目讀起來雖然有些繞口,但它所蘊(yùn)涵的知識卻對設(shè)計(jì)更強(qiáng)大的ava程序有很大幫助。在上一節(jié)討論了自定義注解,由此我們可知注解在J2SE5.0中也和類、接口一樣。是程序中的一個(gè)基本的組成部分。既然可以對類、接口進(jìn)行注解,那么當(dāng)然也可以對注解進(jìn)行注解。使用普通注解對注解進(jìn)行注解的方法和對類、接口進(jìn)行注解的方法一樣。所不同的是,J2SE5.0為注解單獨(dú)提供了4種注解,即元注解。元注解理解:注解可以用于注解類(annotateClasses)可以用于注解接口(annotateInterfaces)可以用于注解枚舉類型(annotateEnums)因此注解同樣也可以用于注解注解(annotateAnnotations)它們是Target、Retention、Documented和Inherited。下面就分別介紹這4種注解。Target這個(gè)注解理解起來非常簡單。由于target的中文意思是“目標(biāo)”,因此,我們可能已經(jīng)猜到這個(gè)注解和某一些目標(biāo)相關(guān)。那么這些目標(biāo)是指什么呢?大家可以先看看下面的代碼。@Target({ElementType.METHOD})@interfaceMyAnnotation{}@MyAnnotation//錯(cuò)誤的使用publicclassClass1{@MyAnnotation/正/確的使用publicvoidmyMethod1(){}}以上代碼定義了一個(gè)注解MyAnnotation和一個(gè)類Classi,并且使用MyAnnotation分別對Classi和myMethodl進(jìn)行注解。如果編譯這段代碼是無法通過的。也許有些人感到驚訝,沒錯(cuò)??!但問題就出S@Target({ElementType.METHOD})上,由于Target使用了一個(gè)枚舉類型屬性,它的值是ElementType.METHOD。這就表明MyAnnotation只能為分法注解。帚不能為其它的任何語言元素進(jìn)行注解。因此,MyAnnotation自然也不能為Class1進(jìn)行注解了。說到這,大家可能已經(jīng)基本明白了。原來target所指的目標(biāo)就是java的語言元素。如類、接口、方法等。當(dāng)然,Target還可以對其它的語言元素進(jìn)行限制,如構(gòu)造函數(shù)、字段、參數(shù)等。如只允許對方法和構(gòu)造函數(shù)進(jìn)行注解可以寫成:@Target({ElementType.METHOD,ElementType.CONSTRUCTOR})@interfaceMyAnnotation{}Retention既然可以自定義注解,當(dāng)然也可以讀取程序中的注解(如何讀取注解將在下一節(jié)中討論)。但是注解只有被保存在lass文件中才可以被讀出來。而Retention就是為設(shè)置注解是否保存在class文件中而存在的。下面的代碼是Retention的詳細(xì)用法。@Retention(RetentionPolicy.SOURCE)@interfaceMyAnnotationi{}@Retention(RetentionPolicy.CLASS)@interfaceMyAnnotation2{}@Retention(RetentionPolicy.RUNTIME)@interfaceMyAnnotation3{}其中第一段代碼的作用是不將注解保存在class文件中,也就是說象“//'一樣在編譯時(shí)被過濾掉了。第二段代碼的作用是只將注解保存在Dlass文件中,而使用反射讀取注解時(shí)忽略這些注解。第三段代碼的作用是即將注解保存在ilass文件中,也可以通過反射讀取注解。Documented這個(gè)注解和它的名子一樣和文檔有關(guān)。在默認(rèn)的情況下在使用avadoc自動(dòng)生成文檔時(shí),注解將被忽略掉。如果想在文檔中也包含注解,必須使用Documented為文檔注解。@interfaceMyAnnotation{}@MyAnnotationclassClassi{publicvoidmyMethod(){}}使用javadoc為這段代碼生成文檔時(shí)并不〉l^@MyAnnotation包含進(jìn)去。生成的文檔對Class1的描述如下:classClassiextendsjava.lang.Object而如果這樣定乂MyAnnotation將會出現(xiàn)另結(jié)果。@Documented@interfaceMyAnnotation{}生成的文檔:@MyAnnotation//這行是在加±@Documented后被加上的classClass1extendsjava.lang.ObjectInherited繼承是java主要的特性之一。在類中的protected和public成員都將會被子類繼承,但是父類的注解會不會被子類繼承呢?很遺憾的告訴大家,在默認(rèn)的情況下,父類的注解并不會被子類繼承。如果要繼承,就必須加上Inherited注解。@Inherited@interfaceMyAnnotation{}@MyAnnotationpublicclassParentClass{}publicclassChildClassextendsParentClass{}在以上代碼中ChildClass和Parentclass—樣都已被MyAnnotation注解了。五、如何使用反射讀取注解前面討論了如何自定義注解。但是自定義了注解又有什么用呢?這個(gè)問題才是J2SE5.0提供注解的關(guān)鍵。自定義注解當(dāng)然是要用的。那么如何用呢?解決這個(gè)問題就需要使用java最令人興奮的功能之一:反射(reflect)。在以前的JDK版本中,我們可以使用反射得到類的方法、方法的參數(shù)以及其它的類成員等信息。那么在J2SE5.0中同樣也可以象方法一樣得到注解的各種信息。在使用反射之前必須使用importjava.lang.reflect.*來導(dǎo)入和反射相關(guān)的類。如果要得到某一個(gè)類或接口的注解信息,可以使用如下代碼:Annotationannotation=TestAnnotation.class.getAnnotation(MyAnnotation.class);如果要得到全部的注解信息可使用如下語句:Annotation[]annotations=TestAnnotation.class.getAnnotations();或Annotation[]annotations=TestAnnotation.class.getDeclaredAnnotations();getDeclaredAnnotations與getAnnotations類似,但它們不同的是getDeclaredAnnotations得到的是當(dāng)前成員所有的注解,不包括繼承的。而getAnnotations得到的是包括繼承的所有注解。如果要得到其它成員的注解,可先得到這個(gè)成員,然后再得到相應(yīng)的注解。如得到myMethod的注解。Methodmethod=TestAnnotation.class.getMethod("myMethod",null);Annotationannotation=method.getAnnotation(MyAnnotation.class);注:要想使用反射得到注解信息,這個(gè)注解必須使用@Retention(RetentionPolicy.RUNTIME)進(jìn)行注解。六、注解的本質(zhì):注解是—種類型JDK5.0中的類型:1、類(class)2、接口(interface)3、枚舉(enum)4、注解(Annotation)因此,注解與其他3種類型一樣,都可以定義、使用,以及包含有自己的屬性、方法七、注解的分類:標(biāo)記注釋:注解的內(nèi)部沒有屬性,稱作標(biāo)記注解使用方法:@注解名使用例子:@MarkAnnotation單值注解:注解的內(nèi)部只有一個(gè)屬性,稱作單值注解使用方法:@注解名(屬性名=屬性值)使用例子:@SingleAnnotation(value="abc")〃也可以寫成@SingleAnnotation("abc")*(屬性名=屬性值)可以簡化為(屬性值)但是需要滿足以下兩個(gè)條件:1、該注解必須為單值注解2、該注解的屬性名必須為value多值注解:注解的內(nèi)部有多個(gè)屬性,稱作多值注解使用方法:@注解名(屬性名1=屬性值1,屬性名2=屬性值2……)使用例子:@MultipliedAnnotation(value1="abc",value2=30)八、自動(dòng)測試機(jī)的寫法:自動(dòng)測試機(jī)的原理:使用Annotation來Annotate元素的實(shí)質(zhì)是:每一個(gè)ElementType內(nèi)部的元素都有兩個(gè)方法,分別為(注:為方便理解,以下使用的TestCase為某個(gè)特定的自定義注釋)⑴isAnnotationPresent(TestCase.class)//判斷該元素是否被TestCase所注釋(2)getAnnotation(TestCase.class)/獲得TestCase的類對象因此,自動(dòng)測試機(jī)的工作過程是:首先通過反射,獲得被測類o中的每一個(gè)方法對每一個(gè)方法通過使用sAnnotationPresent(TestCase.class)判斷其是否被TestCase所注釋(注意是.class!)如果某方法method被TestCase所注釋,則通過method的getAnnotation(TestCase.class)獲得TestCase的類對象tc通過tc的value()方法,獲得該類對象的屬性value(注:此處使用的value(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論