版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
模塊一基礎(chǔ)技能訓(xùn)練模塊《電商web云平臺(tái)開發(fā)》思維導(dǎo)圖目錄CONTENTS搭建電商平臺(tái)Spring業(yè)務(wù)層搭建電商平臺(tái)的Web項(xiàng)目—SpringMVC展示層搭建電商平臺(tái)數(shù)據(jù)處理MyBatis項(xiàng)目123電商平臺(tái)SSM三層框架整合4項(xiàng)目一
搭建電商平臺(tái)Spring業(yè)務(wù)層項(xiàng)目背景SSM框架是Spring+SpringMVC+MyBatis三大框架的整合,是目前比較主流的JavaEE企業(yè)級(jí)框架,用于搭建各種大小型的企業(yè)級(jí)應(yīng)用系統(tǒng)。Spring是一個(gè)控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架,SpringMVC是一個(gè)基于MVC設(shè)計(jì)模式的輕量級(jí)web框架,MyBatis是一個(gè)基于java的持久層框架。SpringSpringMVCMyBatisSSM框架本章節(jié)主要針對(duì)Spirng框架的學(xué)習(xí)和應(yīng)用做詳細(xì)的講解,故本章主要研究?jī)?nèi)容如下:研究?jī)?nèi)容認(rèn)知Spring概念、作用、特性Spring的IOC和依賴注入Spring的AOP實(shí)現(xiàn)模式學(xué)習(xí)目標(biāo)1.了解Spring結(jié)構(gòu)體系;2.理解Spring與IoC的概念和思想;3.認(rèn)識(shí)SpringAOP(面像切面編程)。知識(shí)目標(biāo)1.能夠熟練使用Spring配置文件進(jìn)行配置;2.能夠熟練使用BeanFactory等方法實(shí)現(xiàn)Bean的裝備;3.能夠熟練使用基于XML方式的DI、基于注解的DI;4.能夠熟練使用自動(dòng)代理、Spring-Aop的切面、Spring-AspectJ配置事務(wù)管理。技能目標(biāo)1.培養(yǎng)學(xué)生的主動(dòng)性、執(zhí)行力;2.鍛煉學(xué)生工作中膽大心細(xì);3.鍛煉學(xué)生邏輯思維能力;4.培養(yǎng)學(xué)生有探索創(chuàng)新精神。素養(yǎng)目標(biāo)任務(wù)三Spring的AOP實(shí)現(xiàn)模式預(yù)備知識(shí)一、AOP簡(jiǎn)介ABC日志記錄安全控制參數(shù)校驗(yàn)GFED事務(wù)處理統(tǒng)一異常處理緩存:實(shí)現(xiàn)緩存存取和清除統(tǒng)一發(fā)信、聽通知預(yù)備知識(shí)二、AOP編程術(shù)語切面(Aspect)泛指交叉業(yè)務(wù)邏輯。實(shí)際就是對(duì)主業(yè)務(wù)邏輯的一種增強(qiáng)??椚耄╓eaving)是指將切面代碼插入到目標(biāo)對(duì)象的過程。連接點(diǎn)(JoinPoint)指可以被切面織入的方法。通常業(yè)務(wù)接口中的方法均為連接點(diǎn)。切入點(diǎn)(Pointcut)被標(biāo)記為final的方法是不能作為連接點(diǎn)與切入點(diǎn)的。目標(biāo)對(duì)象(Target)指將要被增強(qiáng)的對(duì)象,即包含主業(yè)務(wù)邏輯的類的對(duì)象。通知(Advice)是切面的一種實(shí)現(xiàn),可以完成簡(jiǎn)單織入功能。顧問(Advisor)是切面的另一種實(shí)現(xiàn)是將通知包裝為更復(fù)雜切面的裝配器。預(yù)備知識(shí)三、了解AspectJCBA編譯后利用ajc編譯器向.class文件和.jar文件中織入增強(qiáng)代碼編譯時(shí)使用ajc編譯器替代javac編譯器,在源文件編譯成.class文件時(shí)織入增強(qiáng)代碼加載時(shí)利用aspectjweaver.jar,使用動(dòng)態(tài)dialing的方式在類加載期間織入切面AspectJ不同階段的實(shí)現(xiàn)方式:(一)AspectJ的簡(jiǎn)介預(yù)備知識(shí)三、了解AspectJ(二)AspectJ的切入點(diǎn)表達(dá)式04010302
[declaring-type-pattern]全限定性類名name-pattern(param-pattern)方法名(參數(shù)名)
execution[modifiers-pattern]訪問權(quán)限類型
ret-type-pattern返回值類型注意:表達(dá)式中加[]的部分表示可省略部分,各部分間用空格分開。預(yù)備知識(shí)三、了解AspectJ(二)AspectJ的切入點(diǎn)表達(dá)式符號(hào)意義*0至多個(gè)任意字符..用在方法參數(shù)中,標(biāo)識(shí)任意多個(gè)參數(shù),用在包名后,表示當(dāng)前包及其子包路徑+用在類名后,標(biāo)識(shí)當(dāng)前類及其子類,用在接口后,標(biāo)識(shí)當(dāng)前接口及其實(shí)現(xiàn)類表達(dá)式中還可以使用以下符號(hào)舉例execution(*set*(..))指定切入點(diǎn)為:任何一個(gè)以“set”開始的方法。預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(一)事務(wù)管理器接口是PlatformTransactionManager接口對(duì)象,其主要功能是實(shí)現(xiàn)完成事務(wù)的提交、回滾及獲取事務(wù)的狀態(tài)信息。預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(一)事務(wù)管理器接口DataSourceTransactionManager使用JDBC或iBatis進(jìn)行持久化數(shù)據(jù)時(shí)使用HibernateTransactionManager使用Hibernate進(jìn)行持久化數(shù)據(jù)時(shí)使用1.PlatformTransactionManager接口的兩個(gè)實(shí)現(xiàn)類LOREM預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(一)事務(wù)管理器接口2.Spring的回滾方式Throwable類是Java語言中所有錯(cuò)誤或異常的超類。Error是程序在運(yùn)行過程中出現(xiàn)的無法處理的錯(cuò)誤。預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(一)事務(wù)管理器接口在代碼編寫時(shí)要求必須捕獲或拋出的異常,若不處理則無法通過編譯。受查異常是RuntimeException類或其子類在運(yùn)行時(shí)才出現(xiàn)的異常。運(yùn)行時(shí)異常3.異常預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(二)事務(wù)定義接口231事務(wù)隔離級(jí)別事務(wù)定義接口TransactionDefinition中定義了事務(wù)描述相關(guān)的三類常量。事務(wù)傳播行為事務(wù)默認(rèn)超時(shí)時(shí)限預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(二)事務(wù)定義接口1.事務(wù)隔離級(jí)別DEFAULT采用DB默認(rèn)的事務(wù)隔離級(jí)別READ_UNCOMMITTED讀未提交。未解決任何并發(fā)問題READ_COMMITTED讀已提交。解決臟讀,存在不可重復(fù)讀與幻讀REPEATABLE_READ可重復(fù)讀。解決臟讀、不可重復(fù)讀,存在幻讀SERIALIZABLE串行化。不存在并發(fā)問題預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(二)事務(wù)定義接口2.事務(wù)傳播行為REQUIRED:指定的方法必須在事務(wù)內(nèi)執(zhí)行。NOT_SUPPORTED:指定的方法不能在事務(wù)環(huán)境中執(zhí)行。REQUIRES_NEW:總是新建一個(gè)事務(wù)。SUPPORTS:指定的方法支持當(dāng)前事務(wù)。MANDATORY:指定的方法必須在當(dāng)前事務(wù)內(nèi)執(zhí)行。NEVER:指定的方法不能在事務(wù)環(huán)境下執(zhí)行。NESTED:指定的方法必須在事務(wù)內(nèi)執(zhí)行。預(yù)備知識(shí)四、了解Spring事務(wù)管理的接口(二)事務(wù)定義接口3.事務(wù)默認(rèn)超時(shí)時(shí)限常量TIMEOUT_DEFAULT定義了事務(wù)底層默認(rèn)的超時(shí)時(shí)限和不支持事務(wù)超時(shí)時(shí)限設(shè)置的none值。它定義了默認(rèn)事務(wù)的超時(shí)時(shí)限。需要注意:由于影響事務(wù)超時(shí)時(shí)限發(fā)揮作用的條件比較多、超時(shí)的時(shí)間計(jì)算比較復(fù)雜,該值一般就使用默認(rèn)值即可。實(shí)施準(zhǔn)備我們認(rèn)識(shí)了Spring的IoC和依賴注入相關(guān)的知識(shí)與開發(fā)技術(shù)之后,需進(jìn)一步理解并掌握AOP切面的基礎(chǔ)知識(shí),包括AOP應(yīng)用場(chǎng)景、AOP編程術(shù)語、AspectJ的切入點(diǎn)表達(dá)式、Spring事務(wù)管理的接口等,為搭建AOP開發(fā)環(huán)境和開發(fā)AOP實(shí)現(xiàn)模式提前做好準(zhǔn)備。任務(wù)實(shí)施與分析步驟1.AOP開發(fā)環(huán)境搭建在原有Spring基本jar包的基礎(chǔ)上再導(dǎo)入AOP聯(lián)盟的規(guī)范(接口)包及Spring對(duì)其的實(shí)現(xiàn)包。步驟1.1:導(dǎo)入jar包步驟1.2:使用原Beans的約束<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans/spring-beans.xsd">任務(wù)實(shí)施與分析步驟2:掌握通知adivce//主業(yè)務(wù)接口publicinterfaceISomeService{
//目標(biāo)方法 voiddoFirst();
//目標(biāo)方法 voiddoSecond();}//目標(biāo)類publicclassSomeServiceImplimplementsISomeService{ @Override publicvoiddoFirst(){
System.out.println("執(zhí)行doFirst()方法"); } @Override publicvoiddoSecond(){
System.out.println("執(zhí)行doSecond()方法"); }}在目標(biāo)方法執(zhí)行之前先執(zhí)行010302不改變目標(biāo)方法執(zhí)行的結(jié)果不改變目標(biāo)方法的執(zhí)行流程,前置通知代碼不能阻止目標(biāo)方法執(zhí)行步驟2.1:學(xué)習(xí)前置通知MethodBeforeAdvice任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.1:學(xué)習(xí)前置通知MethodBeforeAdvice//前置通知publicclassMyMethodBeforeAdviceimplementsMethodBeforeAdvice{
//當(dāng)前方法在目標(biāo)方法執(zhí)行之前執(zhí)行
//method:目標(biāo)方法 //args:目標(biāo)方法的參數(shù)列表
//target:目標(biāo)對(duì)象 @Override publicvoidbefore(Methodmethod,Object[]args,Objecttarget) throwsThrowable{
//對(duì)于目標(biāo)方法的增強(qiáng)代碼就應(yīng)該寫在這里
System.out.println("執(zhí)行前置通知方法"); }}(1)定義前置通知任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.1:學(xué)習(xí)前置通知MethodBeforeAdvice<!--注冊(cè)目標(biāo)對(duì)象--><beanid="someService"class="com.framework.aop01.SomeServiceImpl"/><!--注冊(cè)切面:通知--><beanid="myAdvice"class="com.framework.aop01.MyMethodBeforeAdvice"/><!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <!--<propertyname="targetName"value="someService"/>--> <!--指定目標(biāo)對(duì)象--> <propertyname="target"ref="someService"/> <!--指定切面--> <propertyname="interceptorNames"value="myAdvice"/></bean>(2)配置文件配置任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.1:學(xué)習(xí)前置通知MethodBeforeAdvice@Testpublicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/aop01/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); ISomeServiceservice=(ISomeService)ac.getBean("serviceProxy"); service.doFirst(); System.out.println("=================="); service.doSecond();}(3)編寫測(cè)試類進(jìn)行測(cè)試任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.2:學(xué)習(xí)后置通知AfterReturningAdvice0301
02在目標(biāo)方法執(zhí)行之后執(zhí)行不改變目標(biāo)方法執(zhí)行的結(jié)果不改變目標(biāo)方法的執(zhí)行流程,后置通知代碼不能阻止目標(biāo)方法執(zhí)行IBAOTU.COMIBAOTU.COMIBAOTU.COM任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.2:學(xué)習(xí)后置通知AfterReturningAdvice@OverridepublicStringdoSecond(){
System.out.println("執(zhí)行doSecond()方法"); return"abcde";}(1)修改業(yè)務(wù)接口與實(shí)現(xiàn)類任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.2:學(xué)習(xí)后置通知AfterReturningAdvice//后置通知:可以獲取到目標(biāo)方法的返回結(jié)果,但無法改變目標(biāo)方法的結(jié)果publicclassMyAfterReturningAdviceimplementsAfterReturningAdvice{ //在目標(biāo)方法執(zhí)行之后執(zhí)行 //returnValue:目標(biāo)方法的返回值 @Override publicvoidafterReturning(ObjectreturnValue,Methodmethod, Object[]args,Objecttarget)throwsThrowable{ System.out.println("執(zhí)行后置通知方法returnValue="+returnValue); if(returnValue!=null){ returnValue=((String)returnValue).toUpperCase(); System.out.println("修改過的結(jié)果returnValue="+returnValue); } }}(2)定義切面:通知任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.2:學(xué)習(xí)后置通知AfterReturningAdvice!--注冊(cè)目標(biāo)對(duì)象--><beanid="someService"class="com.framework.aop02.SomeServiceImpl"/><!--注冊(cè)切面:通知--><beanid="myAdvice"class="com.framework.aop02.MyAfterReturningAdvice"/><!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvice"/></bean>(3)修改配置文件配置任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.3:環(huán)繞通知MethodInterceptor//環(huán)繞通知:可以修改目標(biāo)方法的返回結(jié)果publicclassMyMethodInterceptorimplementsMethodInterceptor{ @Override publicObjectinvoke(MethodInvocationinvocation)throwsThrowable{
System.out.println("執(zhí)行環(huán)繞通知:目標(biāo)方法執(zhí)行之前");
//執(zhí)行目標(biāo)方法
Objectresult=invocation.proceed();
System.out.println("執(zhí)行環(huán)繞通知:目標(biāo)方法執(zhí)行之后"); if(result!=null){ result=((String)result).toUpperCase(); } returnresult; }}(1)定義環(huán)繞通知,即方法攔截器。需要注意的是,環(huán)繞通知需要添加MethodInterceptor包。任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.3:環(huán)繞通知MethodInterceptor<!--注冊(cè)目標(biāo)對(duì)象--><beanid="someService"class="com.framework.aop03.SomeServiceImpl"/><!--注冊(cè)切面:通知--><beanid="myAdvice"class="com.framework.aop03.MyMethodInterceptor"/><!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvice"/></bean>(2)修改配置文件配置為環(huán)繞通知配置。任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.3:環(huán)繞通知MethodInterceptor@Testpublicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/aop03/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); ISomeServiceservice=(ISomeService)ac.getBean("serviceProxy"); service.doFirst(); System.out.println("=================="); Stringresult=service.doSecond(); System.out.println(result);}(3)執(zhí)行測(cè)試類,返回結(jié)果被修改。任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.4:異常通知ThrowsAdviceafterThrowing()方法重載的四種形式常用的形式是:publicvoidafterThrowing(自定義的異常類e)。這里的參數(shù)“e”為與具體業(yè)務(wù)相關(guān)的用戶自定義的異常類對(duì)象。容器會(huì)根據(jù)異常類型的不同,自動(dòng)選擇不同的該方法執(zhí)行。任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.4:異常通知ThrowsAdvice@OverridepublicvoiddoFirst(){
System.out.println("執(zhí)行doFirst()方法"+3/0);}//異常通知publicclassMyThrowsAdviceimplementsThrowsAdvice{ //當(dāng)目標(biāo)方法拋出與指定類型的異常具有is-a關(guān)系的異常時(shí),執(zhí)行當(dāng)前方法 publicvoidafterThrowing(Exceptionex){ System.out.println("執(zhí)行異常通知方法"); }}(1)創(chuàng)建異常方法(2)實(shí)現(xiàn)異常通知任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.4:異常通知ThrowsAdvice<!--注冊(cè)目標(biāo)對(duì)象--><beanid="someService"class="com.framework.aop04.SomeServiceImpl"/><!--注冊(cè)切面:通知--><beanid="myAdvice"class="com.framework.aop04.MyThrowsAdvice"/><!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvice"/></bean>(3)修改配置文件為配置異常任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.4:異常通知ThrowsAdvice//創(chuàng)建容器對(duì)象,加載Spring配置文件Stringresource="com/framework/aop04/applicationContext.xml";ApplicationContextac=newClassPathXmlApplicationContext(resource);ISomeServiceservice=(ISomeService)ac.getBean("serviceProxy");service.doFirst();(4)創(chuàng)建測(cè)試類執(zhí)行異常方法。任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.5:學(xué)習(xí)無接口的CGLIB代理生成(1)配置代理,并去掉實(shí)現(xiàn)的接口類<!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvice"/></bean>(2)在測(cè)試類加斷點(diǎn),查看使用的代理任務(wù)實(shí)施與分析步驟2:掌握通知adivce步驟2.6:學(xué)習(xí)有接口的CGLIB代理生成<!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvice"/> <!--<propertyname="optimize"value="true"/>--> <propertyname="proxyTargetClass"value="true"/></bean>在配置文件中增加一個(gè)proxyTargetClass屬性設(shè)置,指定是否對(duì)類進(jìn)行代理。任務(wù)實(shí)施與分析步驟3:掌握顧問AdvisorNameMatchMethodPointcutAdvisor名稱匹配方法切入點(diǎn)顧問ARegexpMethodPointcutAdvisor正則表達(dá)式匹配方法切入點(diǎn)顧問BPointcutAdvisor是顧問的一種,可以指定具體的切入點(diǎn)。PointcutAdvisor接口有兩個(gè)較為常用的實(shí)現(xiàn)類:任務(wù)實(shí)施與分析步驟3:掌握顧問Advisor步驟3.1:學(xué)習(xí)名稱匹配方法切入點(diǎn)顧問<!--注冊(cè)切面:顧問--><beanid="myAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <propertyname="advice"ref="myAdvice"/>
<!--指定切入點(diǎn):這里匹配的對(duì)象是簡(jiǎn)單方法名--> <!--<propertyname="mappedName"value="doFirst"/>--> <!--<propertyname="mappedNames"value="doFirst,doSecond"/>--> <propertyname="mappedNames"value="*ir*"/></bean>
<!--生成代理對(duì)象--><beanid="serviceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvisor"/></bean>(1)修改配置文件,mappedName配置簡(jiǎn)單方法名,mappedNames配置多個(gè)數(shù)組方法名。任務(wù)實(shí)施與分析步驟3:掌握顧問Advisor步驟3.1:學(xué)習(xí)名稱匹配方法切入點(diǎn)顧問@Testpublicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/aop07/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); ISomeServiceservice=(ISomeService)ac.getBean("serviceProxy"); service.doFirst(); System.out.println("=================="); service.doSecond(); System.out.println("=================="); service.doThird();}(2)運(yùn)行測(cè)試類,輸出結(jié)果調(diào)用doFirst,doThird方法任務(wù)實(shí)施與分析步驟3:掌握顧問Advisor步驟3.2:學(xué)習(xí)正則表達(dá)式方法切入點(diǎn)顧問(1)修改配置文件,用正則表達(dá)式配置切入點(diǎn)。<!--注冊(cè)切面:顧問--><beanid="myAdvisor"class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <propertyname="advice"ref="myAdvice"/> <!--這里的正則表達(dá)式匹配的對(duì)象是全限定性方法名--> <!--<propertyname="pattern"value=".*doFirst"/>--> <!--<propertyname="patterns"value=".*doFirst,.*doSecond"/>--> <!--<propertyname="pattern"value=".*doFirst|.*doSecond"/>--> <propertyname="pattern"value=".*S.*"/></bean><!--生成代理對(duì)象--><beanid="serviceProxy"class="org.springframework.aop.framework.ProxyFactoryBean"> <propertyname="target"ref="someService"/> <propertyname="interceptorNames"value="myAdvisor"/></bean>任務(wù)實(shí)施與分析步驟3:掌握顧問Advisor步驟3.2:學(xué)習(xí)正則表達(dá)式方法切入點(diǎn)顧問(2)運(yùn)行測(cè)試類測(cè)試。@Testpublicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/aop08/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); ISomeServiceservice=(ISomeService)ac.getBean("serviceProxy"); service.doFirst(); System.out.println("=================="); service.doSecond(); System.out.println("=================="); service.doThird();}任務(wù)實(shí)施與分析步驟4:掌握自動(dòng)代理生成器,默認(rèn)advisor、Bean名稱默認(rèn)advisor自動(dòng)代理生成器Bean名稱自動(dòng)代理生成器
需要注意的是:自動(dòng)代理生成器的Bean也沒有id屬性,客戶類直接使用目標(biāo)對(duì)象Bean的id。任務(wù)實(shí)施與分析步驟4:掌握自動(dòng)代理生成器,默認(rèn)advisor、Bean名稱步驟4.1配置自動(dòng)代理生成器<!--注冊(cè)切面:顧問--><beanid="myAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <propertyname="advice"ref="myAdvice"/> <propertyname="mappedNames"value="doFirst"/></bean><beanid="myAdvisor2"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <propertyname="advice"ref="myAdvice"/> <propertyname="mappedNames"value="doSecond"/></bean>
<!--注冊(cè)自動(dòng)代理生成器--><beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>任務(wù)實(shí)施與分析步驟4:掌握自動(dòng)代理生成器,默認(rèn)advisor、Bean名稱步驟4.2:Bean名稱自動(dòng)代理生成器注意:只需要修改配置文件中的代理生成配置,及測(cè)試類中的通過getBean()獲取的Bean的id為目標(biāo)類beanId即可。<!--注冊(cè)切面:顧問--><beanid="myAdvisor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <propertyname="advice"ref="myAdvice"/> <propertyname="mappedNames"value="doFirst"/></bean><beanid="myAdvisor2"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <propertyname="advice"ref="myAdvice"/> <propertyname="mappedNames"value="doSecond"/></bean>
<!--注冊(cè)自動(dòng)代理生成器--><beanclass="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <propertyname="beanNames"value="someService"/> <propertyname="interceptorNames"value="myAdvisor"/></bean>(1)修改配置自動(dòng)代理,只調(diào)用MyAdvisor。任務(wù)實(shí)施與分析步驟4:掌握自動(dòng)代理生成器,默認(rèn)advisor、Bean名稱步驟4.2:Bean名稱自動(dòng)代理生成器@Testpublicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/aop10/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); ISomeServiceservice=(ISomeService)ac.getBean("someService"); service.doFirst(); System.out.println("=================="); service.doSecond(); System.out.println("=================="); service.doThird(); System.out.println("-----------------------------"); ISomeServiceservice2=(ISomeService)ac.getBean("someService2"); service2.doFirst(); System.out.println("=================="); service2.doSecond(); System.out.println("=================="); service2.doThird();}(2)執(zhí)行測(cè)試類測(cè)試,了解DefaultAdvisorAutoProxyCreator存在的三個(gè)問題。任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.1:搭建AspectJ的開發(fā)環(huán)境
AOP相關(guān)約束
Spring支持庫解壓目錄中的子目錄org.aspectj下的兩個(gè)子包任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.2:AspectJ基于注解的AOP的實(shí)現(xiàn)//主業(yè)務(wù)接口publicinterfaceISomeService{
//目標(biāo)方法 voiddoFirst();
//目標(biāo)方法
StringdoSecond();
//目標(biāo)方法 voiddoThird();}//目標(biāo)類publicclassSomeServiceImplimplementsISomeService{ @Override publicvoiddoFirst(){
System.out.println("執(zhí)行doFirst()方法"); } @Override publicStringdoSecond(){
System.out.println("執(zhí)行doSecond()方法"); return"abcde"; } @Override publicvoiddoThird(){
System.out.println("執(zhí)行doThird()方法"+3/0);
System.out.println("執(zhí)行doThird()方法"); }}(1)定義業(yè)務(wù)接口與實(shí)現(xiàn)類。任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.2:AspectJ基于注解的AOP的實(shí)現(xiàn)@Aspect//表示當(dāng)前類為切面publicclassMyAspect{ @Before("execution(**..ISomeService.doFirst(..))") publicvoidmyBefore(){ System.out.println("執(zhí)行前置通知方法");}(2)定義切面Pojo類,在定義的Pojo類上添加@Aspect注解任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.2:AspectJ基于注解的AOP的實(shí)現(xiàn)@Before("execution(**..ISomeService.doFirst(..))") publicvoidmyBefore(){ System.out.println("執(zhí)行前置通知方法"); } @Before("execution(**..ISomeService.doFirst(..))") publicvoidmyBefore(JoinPointjp){ System.out.println("執(zhí)行前置通知方法jp="+jp); } @AfterReturning("execution(**..ISomeService.doSecond(..))") publicvoidmyAfterReturning(){ System.out.println("執(zhí)行后置通知方法");}(3)在Pojo類的普通方法上上添加通知注解任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.2:AspectJ基于注解的AOP的實(shí)現(xiàn)<!--注冊(cè)切面--> <beanid="myAspect"class="com.framework.aspectj01.MyAspect"/> <!--注冊(cè)目標(biāo)對(duì)象--> <beanid="someService"class="com.framework.aspectj01.SomeServiceImpl"/> <!--注冊(cè)AspectJ的自動(dòng)代理--><aop:aspectj-autoproxy/>}(4)編寫配置文件,注冊(cè)目標(biāo)對(duì)象與Pojo切面類,注冊(cè)AspectJ的自動(dòng)代理。其工作原理是:<aop:aspectj-autoproxy/>通過掃描找到@Aspect定義的切面類,再由切面類根據(jù)切入點(diǎn)找到目標(biāo)類的目標(biāo)方法,再由通知類型找到切入的時(shí)間點(diǎn)。任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.2:AspectJ基于注解的AOP的實(shí)現(xiàn)@Testpublicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/aspectj01/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); ISomeServiceservice=(ISomeService)ac.getBean("someService"); service.doFirst(); System.out.println("----------------------------"); service.doSecond(); System.out.println("----------------------------"); service.doThird();}(5)編寫測(cè)試類進(jìn)行測(cè)試。任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.3:測(cè)試類中使用的目標(biāo)對(duì)象及注解知識(shí)點(diǎn)。(1)@Before前置通知-增強(qiáng)方法有JoinPoint參數(shù)@AfterReturning后置通知-注解有returning屬性@Before("execution(**..ISomeService.doFirst(..))")publicvoidmyBefore(){
System.out.println("執(zhí)行前置通知方法");}
@AfterReturning(value="execution(**..ISomeService.doSecond(..))",returning="result") publicvoidmyAfterReturning(Objectresult){ System.out.println("執(zhí)行后置通知方法result="+result);}(2)任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.3:測(cè)試類中使用的目標(biāo)對(duì)象及注解知識(shí)點(diǎn)。@Around("execution(**..ISomeService.doSecond(..))")publicObjectmyAround(ProceedingJoinPointpjp)throwsThrowable{
System.out.println("執(zhí)行環(huán)繞通知方法,目標(biāo)方法執(zhí)行之前");
//執(zhí)行目標(biāo)方法
Objectresult=pjp.proceed();
System.out.println("執(zhí)行環(huán)繞通知方法,目標(biāo)方法執(zhí)行之后"); if(result!=null){ result=((String)result).toUpperCase(); } returnresult;}(3)@Around環(huán)繞通知-增強(qiáng)方法有ProceedingJoinPoint參數(shù)任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.3:測(cè)試類中使用的目標(biāo)對(duì)象及注解知識(shí)點(diǎn)。(4)@AfterThrowing異常通知-注解中有throwing屬性@AfterThrowing("execution(**..ISomeService.doThird(..))")publicvoidmyAfterThrowing(){ System.out.println("執(zhí)行異常通知方法");}(5)@After最終通知@After("doThirdPointcut()")publicvoidmyAfter(){ System.out.println("執(zhí)行最終通知方法");}任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.3:測(cè)試類中使用的目標(biāo)對(duì)象及注解知識(shí)點(diǎn)。//定義了一個(gè)切入點(diǎn),叫doThirdPointcut()@Pointcut("execution(**..ISomeService.doThird(..))")publicvoiddoThirdPointcut(){}(6)@Pointcut定義切入點(diǎn)其用法是:將@Pointcut注解在一個(gè)方法之上,以后所有的executeion的value屬性值均可使用該方法名作為切入點(diǎn)。任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)//主業(yè)務(wù)接口publicinterfaceISomeService{ //目標(biāo)方法 voiddoFirst(); //目標(biāo)方法 StringdoSecond(); //目標(biāo)方法 voiddoThird();}步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)(1)定義業(yè)務(wù)接口與實(shí)現(xiàn)類任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)//切面publicclassMyAspect{ publicvoidmyBefore(){ System.out.println("執(zhí)行前置通知方法"); } publicvoidmyBefore(JoinPointjp){ System.out.println("執(zhí)行前置通知方法jp="+jp);
}步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)(2)定義切面Pojo類任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)<!--注冊(cè)切面--> <beanid="myAspect"class="com.framework.xml.MyAspect"/>
<!--注冊(cè)目標(biāo)對(duì)象--><beanid="someService"class="com.framework.xml.SomeServiceImpl"/>步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)(3)注冊(cè)目標(biāo)對(duì)象與Pojo切面類任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)(4)在容器中定義AOP配置<!--AOP配置--> <aop:config> <aop:pointcutexpression="execution(**..ISomeService.doFirst(..))"id="doFirstPointcut"/> <aop:pointcutexpression="execution(**..ISomeService.doSecond(..))"id="doSecondPointcut"/> <aop:pointcutexpression="execution(**..ISomeService.doThird(..))"id="doThirdPointcut"/>
<aop:aspectref="myAspect"> <aop:beforemethod="myBefore"pointcut-ref="doFirstPointcut"/> <aop:beforemethod="myBefore(org.aspectj.lang.JoinPoint)"pointcut-ref="doFirstPointcut"/> <aop:after-returningmethod="myAfterReturning"pointcut-ref="doSecondPointcut"/> <aop:after-returningmethod="myAfterReturning(java.lang.Object)"
任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)
<aop:before>前置通知<aop:after-returning>后置通知<aop:around>環(huán)繞通知<aop:after-throwing>異常通知<aop:after>最終通知<aop:declare-parents>引入通知AspectJ的六種通知的XML標(biāo)簽任務(wù)實(shí)施與分析步驟5:掌握AspectJ對(duì)AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)步驟5.4:AspectJ基于XML的AOP的實(shí)現(xiàn)(5)編寫測(cè)試類進(jìn)行測(cè)試
@Test publicvoidtest01(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="com/framework/xml/applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource);
ISomeServiceservice=(ISomeService)ac.getBean("someService"); service.doFirst(); System.out.println("----------------------------"); service.doSecond(); System.out.println("----------------------------"); service.doThird();
}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.1:導(dǎo)入jar包除了Spring的基本Jar包,數(shù)據(jù)庫驅(qū)動(dòng)Jar外,還需要導(dǎo)入兩個(gè)Jar包。任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.2:搭建測(cè)試環(huán)境publicclassStudent{ privateIntegerid; privateStringname; privateintage; publicStudent(){
super(); //TODOAuto-generatedconstructorstub } publicStudent(Stringname,intage){
super();
=name; this.age=age; } publicIntegergetId(){ returnid; }(1)定義實(shí)體類Student(2)創(chuàng)建數(shù)據(jù)庫測(cè)試表test任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.2:搭建測(cè)試環(huán)境(3)定義IstudentDaopublic
interfaceIStudentDao{
voidinsertStudent(Studentstudent);
voiddeleteById(int
id);
voidupdateStudent(Studentstudent);
List<String>selectAllStudentsNames();
StringselectStudentNameById(int
id);
List<Student>selectAllStudents(); StudentselectStudentById(int
id);}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.2:搭建測(cè)試環(huán)境(4)初步定義StudentDaoImplpublicclassStudentDaoImplextendsJdbcDaoSupportimplementsIStudentDao{ @Override publicvoidinsertStudent(Studentstudent){}這里僅定義一個(gè)
UserDaoImpl類實(shí)現(xiàn)了IUserDao接口,但不具體寫每個(gè)方法的方法實(shí)現(xiàn),保持默認(rèn)即可。任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.2:搭建測(cè)試環(huán)境(5)定義IstudentServicepublicinterfaceIStudentService{ voidaddStudent(Studentstudent); voidremoveById(intid); voidmodifyStudent(Studentstudent); List<String>findAllStudentsNames(); StringfindStudentNameById(intid); List<Student>findAllStudents(); StudentfindStudentById(intid);}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.2:搭建測(cè)試環(huán)境(6)定義StudentServiceImpl實(shí)現(xiàn)類publicclassStudentServiceImplimplementsIStudentService{ privateIStudentDaodao; publicvoidsetDao(IStudentDaodao){ this.dao=dao; } @Override publicvoidaddStudent(Studentstudent){ dao.insertStudent(student);}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.2:搭建測(cè)試環(huán)境(7)定義測(cè)試類MyTestpublicclassMyTest{ privateIStudentServiceservice; @Before publicvoidbefore(){ //創(chuàng)建容器對(duì)象,加載Spring配置文件 Stringresource="applicationContext.xml"; ApplicationContextac=newClassPathXmlApplicationContext(resource); service=(IStudentService)ac.getBean("studentService"); } @Test publicvoidtest01(){ Studentstudent=newStudent("張三",23); service.addStudent(student);}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.3:配置數(shù)據(jù)源(1)Spring默認(rèn)的數(shù)據(jù)源Spring默認(rèn)數(shù)據(jù)源AbstractDriverBasedDataSource的三個(gè)屬性任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.3:配置數(shù)據(jù)源(2)DBCP數(shù)據(jù)源DBCP數(shù)據(jù)源是BasicDataSource,通過快捷操作“Ctrl+O”查看其類結(jié)構(gòu)可看到,其有driverClassName、url、username、password四個(gè)DB連接屬性。任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.3:配置數(shù)據(jù)源(3)C3p0數(shù)據(jù)源C3p0依賴的jar包ComboPooledDataSource類結(jié)構(gòu)任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.3:配置數(shù)據(jù)源(3)C3p0數(shù)據(jù)源數(shù)據(jù)庫連接信息配置文件<!--注冊(cè)數(shù)據(jù)源:C3p0--> <beanid="myDataSource"class="com.mchange.v2.C3p0.ComboPooledDataSource"> <propertyname="driverClass"value="${jdbc.driver}"/> <propertyname="jdbcUrl"value="${jdbc.url}"/> <propertyname="user"value="${jdbc.user}"/> <propertyname="password"value="${jdbc.password}"/></bean>任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.3:配置數(shù)據(jù)源(3)C3p0數(shù)據(jù)源<!--注冊(cè)屬性文件:方式一--> <!-- <beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <propertyname="location"value="classpath:perties"/> </bean> -->context約束任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.4:配置JDBC模板JDBC模板類JdbcTemplate從其父類JdbcAccessor繼承了一個(gè)屬性dataSource,用于接收數(shù)據(jù)源。<!--注冊(cè)JdbcTemplate--> <!-- <beanid="myJdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"> <propertyname="dataSource"ref="myDataSource"/> </bean> -->任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.4:配置JDBC模板<!--注冊(cè)JdbcTemplate--> <!-- <beanid="myJdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"> <propertyname="dataSource"ref="myDataSource"/> </bean> <beanid="studentDao"class="com.framework.dao.StudentDaoImpl"> <propertyname="jdbcTemplate"ref="myJdbcTemplate"/> </bean> -->Dao實(shí)現(xiàn)類繼承了JdbcDaoSupport類后,也就具有了JDBC模板屬性。任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.4:配置JDBC模板<!--注冊(cè)Dao--> <beanid="studentDao"class="com.framework.dao.StudentDaoImpl"> <propertyname="dataSource"ref="myDataSource"/></bean>創(chuàng)建JDBC模板對(duì)象任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.5:完成對(duì)DB的增、刪、改操作Dao實(shí)現(xiàn)類使用繼承自JdbcDaoSupport的getTemplate()方法,可以獲取到JDBC模板對(duì)象。publicinterfaceIStudentDao{ voidinsertStudent(Studentstudent); voiddeleteById(intid); voidupdateStudent(Studentstudent); List<String>selectAllStudentsNames(); StringselectStudentNameById(intid); List<Student>selectAllStudents(); StudentselectStudentById(intid);}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.5:完成對(duì)DB的增、刪、改操作publicclassStudentDaoImplextendsJdbcDaoSupportimplementsIStudentDao{ @Override publicvoidinsertStudent(Studentstudent){ Stringsql="insertintostudent(name,age)values(?,?)"; this.getJdbcTemplate().update(sql,student.getName(),student.getAge()); } @Override publicvoiddeleteById(intid){ Stringsql="deletefromstudentwhereid=?"; this.getJdbcTemplate().update(sql,id); } @Override publicvoidupdateStudent(Studentstudent){ Stringsql="updatestudentsetname=?,age=?whereid=?"; this.getJdbcTemplate().update(sql,student.getName(),student.getAge(),student.getId());}第1個(gè)參數(shù)為要執(zhí)行的SQL語句,第2個(gè)參數(shù)為要執(zhí)行的SQL語句中所包含的動(dòng)態(tài)參數(shù).任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.6:完成對(duì)DB的查詢操作查詢結(jié)果為單個(gè)對(duì)象的queryForObject()與查詢結(jié)果為List的queryForList()。(1)簡(jiǎn)單對(duì)象查詢
@Override publicList<String>selectAllStudentsNames(){ Stringsql="selectnamefromstudent"; returnthis.getJdbcTemplate().queryForList(sql,String.class); } @Override publicStringselectStudentNameById(intid){ Stringsql="selectnamefromstudentwhereid=?"; returnthis.getJdbcTemplate().queryForObject(sql,String.class,id);}任務(wù)實(shí)施與分析步驟6:Spring配置JDBC模板步驟6.6:完成對(duì)DB的查詢操作查詢結(jié)果為單個(gè)對(duì)象的queryForObject()與查詢結(jié)果為List的query()。
(2)自定義對(duì)象查詢publicclassStudentRowMapperimplementsRowMapper<Student>{ //rs:當(dāng)查詢出總的結(jié)果集后
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- Salusin-α-生命科學(xué)試劑-MCE
- 2024年伴熱設(shè)備項(xiàng)目規(guī)劃申請(qǐng)報(bào)告范文
- 2023年瀘州市合江縣考調(diào)機(jī)關(guān)事業(yè)單位人員筆試真題
- 手機(jī)廣告策劃
- 2024年具有獨(dú)立功能電氣設(shè)備及裝置項(xiàng)目申請(qǐng)報(bào)告
- 白描線稿花卉課程設(shè)計(jì)
- 病理生理學(xué)課程設(shè)計(jì)
- 病毒展板設(shè)計(jì)方案
- 班組管理課程設(shè)計(jì)
- 班主任管理策略課程設(shè)計(jì)
- 代理申辦原產(chǎn)地證委托書
- 辦公室工作的職能定位
- 全套企業(yè)管理流程(文字版)
- 檢驗(yàn)科規(guī)章制度
- ICC國際商會(huì)NCNDA和IMFPA中英文對(duì)照可編輯
- 關(guān)于房屋建筑和市政工程界定文件
- 各種表面活性劑耐堿性一覽表
- 我最喜歡的運(yùn)動(dòng)英語作文(精選3篇)
- 北師大版小學(xué)四年級(jí)數(shù)學(xué)上冊(cè)全冊(cè)說課稿
- 【中考英語】中考看圖寫話質(zhì)量分析
- 關(guān)于生態(tài)美育的思考-生態(tài)美育3篇
評(píng)論
0/150
提交評(píng)論