中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

常用網(wǎng)站推薦公司優(yōu)化是什么意思?

常用網(wǎng)站推薦,公司優(yōu)化是什么意思?,網(wǎng)站建設(shè)了解,怎么上網(wǎng)做網(wǎng)站一、Spring IoC(Inversion of Control)中文名稱:控制反轉(zhuǎn)(對(duì)象的創(chuàng)建交給Spring管理)。DI(dependency injection )依賴注入。容器(Container):放置所有被管理的對(duì)象。beans:容器中所有被管理的對(duì)…

一、Spring

  • IoC(Inversion of Control)中文名稱:控制反轉(zhuǎn)(對(duì)象的創(chuàng)建交給Spring管理)。
  • DI(dependency injection )依賴注入。
  • 容器(Container):放置所有被管理的對(duì)象。
  • beans:容器中所有被管理的對(duì)象稱為beans。

一.Spring IOC

1.?介紹

控制反轉(zhuǎn),對(duì)象的創(chuàng)建交給Spring管理。

2.?Bean實(shí)例化的兩種方式(面試題)

2.1.BeanFactory(spring創(chuàng)建對(duì)象)

通過構(gòu)造方法進(jìn)行實(shí)例化。默認(rèn)使用無參構(gòu)造。

?創(chuàng)建方式:

  • <bean> 標(biāo)簽配置。在Spring.xml配置中進(jìn)行bean對(duì)象的創(chuàng)建。
 <bean id="peo" class="com.bjsxt.pojo.People"></bean>
  • @Component及子注解管理對(duì)象,配合 ComponentScan的掃描。
@Service
public class UserServiceImpl implements UserService{}
 <!-- 掃描service中的注解(Component及子注解) --><context:component-scan base-package="com.lyx.service"/>
  • @Bean修飾的方法,方法的返回值交由spring管理,方法名為key。
  • @Import 指定的類由spring管理。

2.2.FactoryBean(使用自定義的工廠類創(chuàng)建對(duì)象)

分為靜態(tài)工廠和實(shí)例工廠兩種方式。靜態(tài)工廠和實(shí)例工廠類最主要的區(qū)別是,創(chuàng)建bean的方法是static修飾的。

1.自定對(duì)象工廠類。

public class PeopleFactory {People peo = new People();public People getInstance(){return peo;}
}

2.工廠交由spring管理,從工廠方法中獲取對(duì)象交由spring管理。

<!-- 創(chuàng)建工廠實(shí)例 -->
<!-- 工廠bean-->
<bean id="factory" class="com.bjsxt.factory.PeopleFactory"></bean><!--- factory-bean:工廠bean的id屬性值。- factory-method:工廠中創(chuàng)建bean的方法。-->
<bean id="peo2" factory-bean="factory" factory-method="getInstance"></bean><!-- 靜態(tài)工廠的配置 --><bean id="peo3" class="com.bjsxt.factory.PeopleStaticFactory" factory-method="newInstance"></bean>
?2.3.bean標(biāo)簽的scope屬性(面試題)

Spring中<bean>的scope控制的是Bean的有效范圍。一共有6個(gè)可取值。

<!--singleton:默認(rèn)值。bean是單例的,每次獲取Bean都是同一個(gè)對(duì)象。prototype:bean時(shí)原型的,每次獲取bean都重新實(shí)例化。request:每次請(qǐng)求重新實(shí)例化對(duì)象,同一個(gè)請(qǐng)求中多次獲取時(shí)單例的。session:每個(gè)會(huì)話內(nèi)bean是單例的。application:整個(gè)應(yīng)用程序?qū)ο髢?nèi)bean是單例的。websocket:同一個(gè)websocket對(duì)象內(nèi)對(duì)象是單例的。
里面的singleton和prototype在Spring最基本的環(huán)境中就可以使用,不需要web環(huán)境。
但是里面的request、session、application、websocket都只有在web環(huán)境才能使用。
-->
<bean id="people" class="com.bjsxt.pojo.People" scope="singleton"></bean>

二.Spring DI(依賴注入)

1.手動(dòng)注入(spring.xml中進(jìn)行配置)

?? 1.構(gòu)造注入(依賴于構(gòu)造方法完成屬性賦值)

<bean id="peo4" class="com.bjsxt.pojo.People">   <constructor-arg type="int" value="1"></constructor-arg>  <constructor-arg type="java.lang.String" value="張三"></constructor-arg>
</bean>

? ?2.設(shè)置注入(依賴于set方法完成屬性賦值)

<bean id="peo5" class="com.bjsxt.pojo.People"><property name="id" value="2"></property><property name="name" value="李四"></property>
</bean>

2.自動(dòng)注入(使用注解)

自動(dòng)注入指的都是bean之間的自動(dòng)注入。能夠自動(dòng)注入必須保證Spring 容器中包含能被自動(dòng)注入的bean。

1.兩種方式進(jìn)行配置:

  • 在根標(biāo)簽<beans>中配置default-autowire屬性?。
  • <bean>標(biāo)簽中配置autowire屬性,和default-autowire取值相同。

2.屬性取值?

  • byName:根據(jù)bean的名字自動(dòng)注入,依賴于set方法。
  • byType:通過類的類型自動(dòng)注入。
  • constructor:通過構(gòu)造方法進(jìn)行注入。調(diào)用有參構(gòu)造方法完成對(duì)象創(chuàng)建及屬性自動(dòng)注入。

?3.@Autowired注解(自動(dòng)注入)

用在類上的注解,先根據(jù)類型找,類型出現(xiàn)多個(gè),再根據(jù)名字找。

1.特殊用法

  • 用在屬性上,使用反射進(jìn)行注入。
  • 用在set方法上,使用set方法注入。
  • 用在有參構(gòu)造方法上,使用有參構(gòu)造進(jìn)行注入。

?2.特點(diǎn)

? ? 注解所在的bean和注入的bean都為spring容器管理的bean。

@Resouce(非spring注解)?:先根據(jù)名字找,沒有找到,再根據(jù)類型找。

三.單例設(shè)計(jì)模式(面試中筆試題)

只創(chuàng)建一個(gè)對(duì)象的設(shè)計(jì)模式。

1. 餓漢式

/*單例:希望類只有一個(gè)核心思想:1. 構(gòu)造方法私有2. 對(duì)外提供一個(gè)能夠獲取對(duì)象的方法。餓漢式:優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單缺點(diǎn):無論是否使用當(dāng)前類對(duì)象,加載類時(shí)一定會(huì)實(shí)例化。*/
public class Singleton {// 之所以叫做餓漢式:因?yàn)轭惣虞d時(shí)就創(chuàng)建了對(duì)象private static Singleton singleton = new Singleton();private Singleton(){}public static Singleton getInstance(){return singleton;}
}

2. 懶漢式

/*** 核心思想:* 1. 構(gòu)造方法私有。* 2. 對(duì)外提供一個(gè)能夠獲取對(duì)象的方法。** 懶漢式優(yōu)點(diǎn)和缺點(diǎn):*  優(yōu)點(diǎn):*      按需創(chuàng)建對(duì)象。不會(huì)在加載類時(shí)直接實(shí)例化對(duì)象。*  缺點(diǎn):*      寫法相對(duì)復(fù)雜。*      多線程環(huán)境下,第一次實(shí)例化對(duì)象效率低。*/
public class Singleton2 {//懶漢式:不會(huì)立即實(shí)例化private static Singleton2 singleton2;private Singleton2() {}public static Singleton2 getInstance() {if (singleton2 == null) {// 不是第一次訪問的線程,直接通過if判斷條件不成立。直接returnsynchronized (Singleton2.class) {if(singleton2==null) {// 防止多個(gè)線程已經(jīng)執(zhí)行到synchronizedsingleton2 = new Singleton2();}}}return singleton2;}
}

四.循環(huán)依賴問題(重要面試題)

1.介紹

循環(huán)注入即多個(gè)類相互依賴,產(chǎn)生了一個(gè)閉環(huán)。

2. 解決循環(huán)依賴 (三級(jí)緩存)

  • 一級(jí)緩存(singletonObjects):存放? 實(shí)例化、屬性注入和初始化完成的對(duì)象。
  • 二級(jí)緩存(earlySingletonObjects):存放早期暴露出來的Bean對(duì)象,實(shí)例化和屬性注入完成的對(duì)象。
  • 三級(jí)緩存(singletonFactories):存放實(shí)例化完成的對(duì)象。存放bean創(chuàng)建工廠,以便于后面擴(kuò)展有機(jī)會(huì)創(chuàng)建代理對(duì)象。

單例模式創(chuàng)建對(duì)象的步驟?:

  1. 實(shí)例化:調(diào)用對(duì)象的構(gòu)造方法實(shí)例化對(duì)象。

  2. 屬性注入:填充屬性,這一步主要是對(duì)bean的依賴屬性進(jìn)行填充。

  3. 初始化:屬性注入后,執(zhí)行自定義初始化操作。

五.BeanFactory和ApplicationContext(經(jīng)典面試題)?

1. BeanFactory接口(懶漢式)

  • BeanFactory是Spring中的頂級(jí)接口,接口中定了Spring容器最基本功能。是Spring IoC的最核心接口。
  • ApplicationContext的getBean方法其實(shí)就是BeanFactory的方法。
  • BeanFactory是在調(diào)用getBean方法的時(shí)候才實(shí)例化Bean。(懶漢式)

BeanFactory最常用實(shí)現(xiàn)類是XmlBeanFactory。但是從Spring 3.1 版本開始,使用DefaultListableBeanFactory和XMLBeanDefinitionReader替代。

?2. ApplicationContext接口(餓漢式)

BeanFactory的子接口。比BeanFactory的功能更加強(qiáng)大,除了BeanFactory的功能,還包含了:

  • AOP 功能
  • 國(guó)際化(MessageSource)
  • 訪問資源,如URL和文件(ResourceLoader)
  • 消息發(fā)送機(jī)制(ApplicationEventPublisher)
  • Spring集成Web時(shí)的WebApplicationContext

ApplicationContext是在加載配置文件后立即實(shí)例化Bean。(餓漢式)

在使用時(shí)ApplicationContext時(shí)多使用ClassPathXmlApplicationContext。

六.動(dòng)態(tài)代理設(shè)計(jì)模式

動(dòng)態(tài)創(chuàng)建代理對(duì)象。

1.JDk動(dòng)態(tài)代理

JDK動(dòng)態(tài)代理是基于接口。先創(chuàng)建接口,然后創(chuàng)建被代理對(duì)象類。

 //JDK動(dòng)態(tài)代理/*功能:JDK動(dòng)態(tài)代理為類創(chuàng)建代理對(duì)象,實(shí)現(xiàn)目標(biāo)對(duì)象功能的增強(qiáng)JDK動(dòng)態(tài)代理為接口創(chuàng)建實(shí)現(xiàn)類*//*Proxy.newProxyInstance中的參數(shù) 參數(shù)一:類加載參數(shù)二:接口的類對(duì)象(JDK動(dòng)態(tài)代理基于接口實(shí)現(xiàn))參數(shù)三:運(yùn)行時(shí)底層實(shí)現(xiàn)select()方法【該過程看不到】,實(shí)現(xiàn)的方法中調(diào)用了 invoke()*/@Testpublic void test01() {//創(chuàng)建被代理對(duì)象UserServicesImpl userServicesImpl = new UserServicesImpl();UserService userService = (UserService) Proxy.newProxyInstance(Test2.class.getClassLoader(),//UserServicesImpl.class.getInterfaces(),//必須為接口的類對(duì)象new InvocationHandler() {//@Override/*invoke方法中的參數(shù):參數(shù)一:代理對(duì)象參數(shù)二:目標(biāo)方法(被代理方法)參數(shù)三:目標(biāo)方法參數(shù)* */public Object invoke(Object o, Method method, Object[] objects) throws Throwable {Object invoke = method.invoke(userServicesImpl, objects);return invoke;}});//代理對(duì)象調(diào)用方法userService.select();}

2.Cglib動(dòng)態(tài)代理?

Cglig動(dòng)態(tài)是第三方提供的技術(shù),需要導(dǎo)入jar包,并且可以是基于類繼承,也可以是基于接口實(shí)現(xiàn)。

使用:先創(chuàng)建接口或類,然后創(chuàng)建被代理的對(duì)象類(繼承或?qū)崿F(xiàn))。

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>

    @Test//2.為類創(chuàng)建代理對(duì)象,實(shí)現(xiàn)目標(biāo)方法的功能增強(qiáng)(基于接口實(shí)現(xiàn))public void test04(){//創(chuàng)建目標(biāo)對(duì)象(被代理對(duì)象)UserServicesImpl userServicesImpl = new UserServicesImpl();Enhancer enhancer = new Enhancer();enhancer.setInterfaces(UserServicesImpl.class.getInterfaces());enhancer.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("前置 增強(qiáng)");//調(diào)用 目標(biāo)方法Object invoke = method.invoke(userServicesImpl, objects);System.out.println("后置 增強(qiáng)");return invoke;}});//獲取代理對(duì)象并調(diào)用方法UserService userService = (UserService) enhancer.create();userService.select();}@Test// 3.為類創(chuàng)建代理對(duì)象,實(shí)現(xiàn)目標(biāo)方法的功能增強(qiáng)(基于繼承實(shí)現(xiàn))public void test05(){Enhancer enhancer = new Enhancer();//增強(qiáng)器enhancer.setSuperclass(Aaa.class);enhancer.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("前置 增強(qiáng)");Object invoke = methodProxy.invokeSuper(o, objects);System.out.println("后置 增強(qiáng)");return invoke;}});//獲取代理對(duì)象調(diào)用方法UserServicesImpl2 userServices = (UserServicesImpl2) enhancer.create();userServices.querry(1,2);}
}

3.總結(jié)

  • JDK動(dòng)態(tài)代理機(jī)制是委托機(jī)制,只能對(duì)實(shí)現(xiàn)了接口的類生成代理,底層通過反射機(jī)制實(shí)現(xiàn)。(重點(diǎn))

  • CGLIB動(dòng)態(tài)代理機(jī)制是接口或繼承機(jī)制,針對(duì)類生成代理,被代理類和代理類是繼承關(guān)系,底層通過字節(jié)碼處理框架asm,修改字節(jié)碼生成子類


七.AOP?

?1. SpringAOP介紹(常見面試題)

面向切面編程是對(duì)面向?qū)ο缶幊痰难a(bǔ)充。?AOP 中模塊化的單位是切面。

AOP中的專業(yè)術(shù)語(yǔ):

Aspect:? ? ? 切面。為方法添加增強(qiáng)功能的過程。

join point:? ?切入點(diǎn)。就是被代理的方法,也叫目標(biāo)方法。

Advice:? ? ? 通知。就是增強(qiáng)內(nèi)容。前置、后置、環(huán)繞、異常等通知。

Pointcut:? ? 切點(diǎn)。就是表達(dá)式,通過切點(diǎn)表達(dá)式可以找到目標(biāo)方法(join point)。

Weaving:? ? 織入??椚刖褪前?通知 添加到 切入點(diǎn) 的過程。

AOP Proxy:代理。Spring支持JDK動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理兩種方式,可以通過proxy-? ? ? ? ? ? ? ? ? ? ? ? ? ? ? target-?class=true把默認(rèn)的JDK動(dòng)態(tài)代理修改為Cglib動(dòng)態(tài)代理。

2. 實(shí)現(xiàn)AOP的兩種方式

1.實(shí)現(xiàn)AOP需要引入依賴:

<!--支持切點(diǎn)表達(dá)式等-->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version>
</dependency>
<dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version>
</dependency>

2.實(shí)現(xiàn)AOP的兩種方式:?

  • Schema-based:所有的通知都需要實(shí)現(xiàn)特定類型的接口實(shí)現(xiàn)通知。

在Schema-based方式中通知的分類(面試題):

  • 前置通知,通知需要實(shí)現(xiàn)MethodBeforeAdvice接口。
  • 后置通知,通知需要實(shí)現(xiàn)AfterReturningAdvice接口。
  • 環(huán)繞通知,通知需要實(shí)現(xiàn)MethodInterceptor接口。
  • 異常通知,通知需要實(shí)現(xiàn)ThrowsAdvice接口。
  <!-- 配置異常通知對(duì)象 --><bean id="mythrow" class="com.bjsxt.advice.MyThrow"/><aop:config><aop:pointcut id="mypoint" expression="execution(* com.bjsxt.service.impl.PeopleServiceImpl.test())"/><!-- 織入異常通知 --><aop:advisor advice-ref="mythrow" pointcut-ref="mypoint"/></aop:config>
</beans>
  • AspectJ:可以使用普通Java類結(jié)合特定的配置實(shí)現(xiàn)通知。

在AspectJ方式中通知的分類(面試題):

  • 前置通知:before。

  • 后置通知:after。

    • after是否出現(xiàn)異常都執(zhí)行的后置通知。

    • after-returning切入點(diǎn)不出現(xiàn)異常時(shí)才執(zhí)行的后置通知。

  • 環(huán)繞通知:around。

  • 異常通知:after-throwing。

	<!-- 配置通知對(duì)象 --><bean id="myadvice2" class="com.bjsxt.advice.MyAdvice2"></bean><aop:config><!-- 基于Aspectj方式配置 --><aop:aspect ref="myadvice2"><!--切點(diǎn)配置args():編寫參數(shù)名,參數(shù)名稱和目標(biāo)方法中參數(shù)名稱一致。--><aop:pointcut id="mypoint" expression="execution(* com.bjsxt.service.impl.PeopleServiceImpl.test(int,boolean)) and args(id1,bool1)"/><aop:before method="mybefore" pointcut-ref="mypoint" arg-names="id1,bool1"/><aop:after-returning method="myafter" pointcut-ref="mypoint" arg-names="id1,bool1"/><aop:after method="myafter2" pointcut-ref="mypoint" arg-names="id1,bool1"/><!-- pjp由Spring自動(dòng)注入 --><aop:around method="myaround" pointcut-ref="mypoint" arg-names="pjp,id1,bool1"/><aop:after-throwing method="mythrow" pointcut-ref="mypoint" arg-names="ex,id1,bool1" throwing="ex"/></aop:aspect></aop:config>

Schema-based和Aspectj的區(qū)別:

  • Schema-based:基于接口實(shí)現(xiàn)的。 AspectJ方式:是基于配置實(shí)現(xiàn)的。
  • Schame-based是運(yùn)行時(shí)增強(qiáng),AspectJ是編譯時(shí)增強(qiáng)。
  • 切面比較多時(shí),最好選擇AspectJ方式,因?yàn)锳spectJ方式要快很多。

3.注解方式實(shí)現(xiàn)AOP

 <!--配置注解掃描路徑--><context:component-scan base-package="com.bjsxt"/><!--配置AOP注解生效--><aop:aspectj-autoproxy expose-proxy="true"/>autoproxy expose-proxy="true"/>

注意:

  1. 配置Spring容器注解掃描的路徑。

  2. 配置AOP注解生效。

@Component相當(dāng)于配置文件的bean標(biāo)簽,將某個(gè)類的對(duì)象掃描到Spring容器中。
@Aspect聲明該類為通知類。結(jié)合@Component在通知類上使用。
@pointcut聲明切點(diǎn),方法上使用。
@Before聲明方法為前置通知方法。
@After聲明方法為后置通知方法。
@Around聲明方法為環(huán)繞通知方法。
@AfterThrowing聲明方法為異常通知方法。

AOP工作流程:
? ? ? ? 1.通過切點(diǎn)表達(dá)式獲取切入點(diǎn)(目標(biāo)對(duì)象和目標(biāo)方法)
? ? ? ? 2.為目標(biāo)對(duì)象創(chuàng)建代理對(duì)象
? ? ? ? 3.在代理對(duì)象中織入通知,執(zhí)行的目標(biāo)方法

?八.Sping聲明式事務(wù)

聲明式事務(wù)是基于AOP實(shí)現(xiàn)的。把開啟事務(wù)的代碼放在前置通知中,把事務(wù)回滾和事務(wù)提交的代碼放在了后置通知中。

1.配置聲明式事務(wù)

需要在配置文件中引入xmlns:tx命名空間。

<!--1. 配置聲明式事務(wù)(事務(wù)開啟,事務(wù)提交,事務(wù)回滾都進(jìn)行了封裝,配合AOP完成事務(wù)的控制 --><!--前置通知:開啟事務(wù)后置通知:事務(wù)提交異常通知:事務(wù)回滾-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 事務(wù)管理必須連接數(shù)據(jù)庫(kù),需要注入數(shù)據(jù)源對(duì)象 --><property name="dataSource" ref="dataSource"></property></bean><!-- 2. 配置事務(wù)通知 配置哪些方法織入事務(wù)的通知 --><!-- 相當(dāng)于通知類,只有方法出現(xiàn)了異常觸發(fā)異常通知,實(shí)現(xiàn)事務(wù)回滾,所以絕對(duì)不能在service里面try...catch--><tx:advice id="txAdvice" transaction-manager="txManager"><!-- 配置的方法才會(huì)織入事務(wù)的通知 --><tx:attributes><!-- --><tx:method name="alertAccountt"/><!--   <tx:method name="select*"/>--><!-- 所有的方法都需要進(jìn)行事務(wù)管理。在配置方法名稱是支持*作為通配符 --><tx:method name="*"/></tx:attributes></tx:advice> <!-- 3. 設(shè)定哪個(gè)方法需要被聲明式事務(wù)管理,使用AOP完成,根據(jù)切點(diǎn)表達(dá)式獲取切入點(diǎn)(目標(biāo)對(duì)象中的目標(biāo)方法),為目標(biāo)對(duì)象創(chuàng)建代理對(duì)象,將通知和目標(biāo)方法完成織入。
--><aop:config><aop:pointcut id="mypoint" expression="execution(*  com.bjsxt.service.impl.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"></aop:advisor></aop:config>

2.注解配置聲明式事務(wù)(主要使用)

Spring 注解配置事務(wù)時(shí),只需要在需要有事務(wù)管理的方法上添加@Transactional注解。

必須保證配置注解的方法所在的類已經(jīng)放入到Spring容器中。

  • 配置注解掃描
<context:component-scan base-package="com.bjsxt.service.impl"></context:component-scan>
  • 開啟事務(wù)注解的支持
<tx:annotation-driven></tx:annotation-driven>
  • 必須配置事務(wù)管理器類
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property>
</bean>
  • @Transactional的使用

@Transactional用在類上,整個(gè)類中方法都生效。

@Transactional用在方法上,該方法生效。用在方法上優(yōu)先級(jí)更高。

3.聲明式事務(wù)四個(gè)基礎(chǔ)屬性

?<tx:method>標(biāo)簽有下面屬性的配置,@Transaction注解也支持部分屬性(如果有則含義相同,如果沒有則表示在注解中不需要配置)。

1. name屬性
配置哪些方法需要有事務(wù)控制,支持*通配符。


2. readonly屬性
是否為只讀事務(wù),有true和false兩種。


3. rollback-for屬性
異常類型全限定路徑,表示出現(xiàn)什么類型的異常進(jìn)行數(shù)據(jù)回滾。 默認(rèn)運(yùn)行時(shí)異常及子類異?;貪L,檢查時(shí)異常不回滾。


4. no-rollback-for屬性
異常類型全限定路徑,當(dāng)出現(xiàn)什么異常的時(shí)候不進(jìn)行數(shù)據(jù)回滾。


5. timeout屬性
執(zhí)行超過了設(shè)置的超時(shí)時(shí)間,回滾操作。(超時(shí)拋出異常)
?

4.事務(wù)傳播行為(面試題)

4.1.介紹

事務(wù)傳播行為:當(dāng)出現(xiàn)service方法調(diào)用另一個(gè)service方法時(shí)(這些方法都被聲明式事務(wù)管理)這些方法如何進(jìn)行事務(wù)管理。?

可以通過進(jìn)行配置tx:method或@Transactional中的propagation屬性來進(jìn)行傳播行為的設(shè)置 。

?@Transactional(propagation = Propagation.MANDATORY)?

  • 默認(rèn)情況下都認(rèn)為每個(gè)方法都是沒有事務(wù)的(事務(wù)自動(dòng)提交)。
  • ?整個(gè)調(diào)用最終都是在調(diào)用者里面統(tǒng)一提交回滾。
  • 在聲明式事務(wù)中,如果是同一個(gè)類的多個(gè)方法相互調(diào)用,屬于同一個(gè)事務(wù)。

因?yàn)槁暶魇绞聞?wù)是基于AOP實(shí)現(xiàn)的,AOP是基于動(dòng)態(tài)代理實(shí)現(xiàn)的,為同一個(gè)對(duì)象創(chuàng)建一個(gè)代理對(duì)象,所以實(shí)現(xiàn)出來的效果只有對(duì)第一個(gè)調(diào)用的方法添加上了聲明式事務(wù)管理,其他方法都是普通的方法調(diào)用。

4.2?propagation屬性的可選值
Propagation.REQUIRED(默認(rèn))當(dāng)前有事務(wù),使用當(dāng)前事務(wù)。當(dāng)前沒有事務(wù),開啟新的事務(wù)。
Propagation.NEVER必須在非事務(wù)狀態(tài)下執(zhí)行。沒有事務(wù),正常運(yùn)行。有事務(wù),拋出異常。
Propagation.NESTED必須在事務(wù)狀態(tài)下執(zhí)行。沒有事務(wù),創(chuàng)建事務(wù)。有事務(wù),創(chuàng)建嵌套事務(wù)。
Propagation.REQUIRES_NEW沒有事務(wù),創(chuàng)建事務(wù)。有事務(wù),掛起當(dāng)前事務(wù),創(chuàng)建新的事務(wù)。最后統(tǒng)一操作。
SUPPORTS沒有事務(wù),非事務(wù)執(zhí)行。有事務(wù),使用當(dāng)前事務(wù)。
Propagation.NOT_SUPPORTED非事務(wù)下執(zhí)行。有事務(wù),掛起事務(wù),以非事務(wù)執(zhí)行,執(zhí)行后,恢復(fù)掛起的事務(wù)。
propagation = Propagation.MANDATORY事務(wù)下執(zhí)行。沒有事務(wù),拋出異常。

九、Bean的生命周期(非常重要)

Spring中Bean的生命周期就是指Bean從初始化到銷毀的過程。Bean最簡(jiǎn)單的實(shí)現(xiàn)就是直接使用<bean>標(biāo)簽定義這個(gè)Bean。

Bean生命周期流程:

  1. 編寫bean的定義信息(xml,注解)。
  2. 通過BeanDefinitionReader 讀取bean的定義信息。
  3. 解析出bean的定義信息。
  4. 可以通過BeanFactoryPostProcessor接口實(shí)現(xiàn)類,操作bean的定義信息。
  5. 實(shí)例化bean對(duì)象。
  6. 屬性注入。
  7. 可以使用相關(guān)的Aware接口,獲取bean的相關(guān)信息,容器信息...。
  8. 可以使用BeanPostProcessor接口中before方法操作對(duì)象。
  9. 可以使用init-method調(diào)用自定義的初始化方法。
  10. 可以使用BeanPostProcessor接口中after方法操作對(duì)象。
  11. 存儲(chǔ)到單例池(一級(jí)緩存中)。

二、Sping MVC

一. Spring MVC介紹

  • Spring MVC本質(zhì)為Spring 框架的一個(gè)擴(kuò)展 ,屬于Spring Framework的二級(jí)子項(xiàng)目。
  • Spring MVC是基于Front設(shè)計(jì)模式。
  • Spring MVC中有前端入口DispatcherServlet,里面編寫了請(qǐng)求分發(fā)功能。
  • EmpController在Spring MVC稱為控制器類(Handler),里面的方法稱為:控制單元(HandlerMethod)。

MVC三層中都有自己的功能。例如:

  • M:在模型層包含:數(shù)據(jù)校驗(yàn)。
  • V:在視圖層包含:國(guó)際化、標(biāo)簽庫(kù)。
  • C:在控制層包含的功能就更多了:轉(zhuǎn)發(fā)重定向、參數(shù)、攔截器、作用域等。

Spring中的父子容器問題:

二.Spring MVC環(huán)境搭建

導(dǎo)入依賴:

 <!-- 依賴了Spring框架核心功能的5個(gè)依賴以及Spring整合Web的依賴spring-web --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.16</version></dependency>

?配置springMVC.xml:

   <context:component-scan base-package="com.bjsxt.controller"></context:component-scan><!-- 讓Spring MVC的注解生效 不要引錯(cuò)xsd--><mvc:annotation-driven></mvc:annotation-driven>

編寫web.xml內(nèi)容:

  <servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><!-- 參數(shù)名稱必須叫做:contextConfigLocation。單詞和大小寫錯(cuò)誤都導(dǎo)致配置文件無法正確加載 --><param-name>contextConfigLocation</param-name><!-- springmvc.xml 名稱自定義,只要和后面創(chuàng)建的文件名稱對(duì)應(yīng)就可以了。 --><param-value>classpath:springmvc.xml</param-value></init-param><!-- Tomcat啟動(dòng)立即加載Servlet,而不是等到訪問Servlet才去實(shí)例化DispatcherServlet --><!-- 配置上的效果:Tomcat啟動(dòng)立即加載Spring MVC框架的配置文件--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- /表示除了.jsp結(jié)尾的uri,其他的uri都會(huì)觸發(fā)DispatcherServlet。此處前往不要寫成 /* --><url-pattern>/</url-pattern></servlet-mapping>

創(chuàng)建控制器類:

@Controller// 放入到Spring MVC容器中
public class FirstController {/** 官方標(biāo)準(zhǔn)寫法:*      返回值是ModelAndView,對(duì)象中存儲(chǔ)跳轉(zhuǎn)資源路徑及作用域值*/// 當(dāng)前方法的映射路徑@RequestMapping("/first")public ModelAndView test1(){ModelAndView modelAndView = new ModelAndView("first.jsp");return modelAndView;}/** 簡(jiǎn)化寫法(平時(shí)使用的方式)*      返回值是String,表示跳轉(zhuǎn)的資源路徑*/@RequestMapping("/first2")public String test2(){return "first.jsp";}
}

三.@RequestMapping注解

1.使用

  • @RequestMapping注解可以寫在控制器類上,也可以寫在控制單元方法上。
  • 如果寫在類上,表示當(dāng)前類所有控制單元的映射路徑,都以指定路徑開頭。
  • 如果寫在方法上,表示當(dāng)前方法的映射路徑。

2.注解的屬性

? 1.path:映射的路徑。
? ? ? ? ? ?映射一個(gè)訪問路徑:path = {"aa"} ?省略{} ? path = "aa"
? ? ? ? ? ?映射多個(gè)訪問路徑:path = {"aa,bb"}。
??2.value:和path作用相同,只有一個(gè)value屬性時(shí),value可以省略。
? 3.name:添加描述信息。
? 4.method:允許的請(qǐng)求方式。
? ? ? ? ? ? ? ?RequestMethod.POST
? ? ? ? ? ? ? ?RequestMethod.GET
? ? ? ? ? ? ? ...
? ? ? ? ? ? 簡(jiǎn)化:
? ? ? ? ? ? ? ?@GetMapping? 為? @RequestMapping(method = RequestMethod.GET)
? ? ? ? ? ? ? ?@PostMapping? 為? @RequestMapping(method = RequestMethod.POST)
? ? ? ? ? ? ? ?...
? ?5.params: ?指定請(qǐng)求中必須攜帶的請(qǐng)求參數(shù)。
? ?6.headers: 指定請(qǐng)求中必須攜帶的請(qǐng)求頭。

? ?7.consumes:表示處理請(qǐng)求內(nèi)容(Content-Type)的類型。
? ?8.produces:配合@ResponseBody注解使用,指定響應(yīng)內(nèi)容的類型。單獨(dú)使用沒有意? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 義。

四.轉(zhuǎn)發(fā)和重定向(重要)

  • 在Spring MVC框架中,默認(rèn)情況下都使用轉(zhuǎn)發(fā)進(jìn)行尋找資源。
  • 在資源路徑前面添加 forward:? ?,?表示轉(zhuǎn)發(fā)。
  • 在資源路徑前面添加?redirect:?,表示重定向。

五.靜態(tài)資源放行

<!--配置靜態(tài)資源放行--><!--mapping:當(dāng)URI是什么樣格式時(shí),不再執(zhí)行控制器,而是尋找靜態(tài)資源。 ** 是通配符,表示任意層路徑 --><!--location:去哪個(gè)目錄中尋找靜態(tài)資源。mapping中**的值是什么,就去location目錄中找對(duì)應(yīng)資源--><!--例如URL是http://localhost:8080/bjsxt/js/jquery.js 其中mapping的**就是jquery.js,就會(huì)去location的/js/目錄中尋找jquery.js -->
<mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
<mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
<mvc:resources mapping="/images/**" location="/images/"></mvc:resources><!-- 靜態(tài)資源沒有在WEB-IBF中可以使用該方式  --><mvc:default-servlet-handler/>

六.控制單元的參數(shù)(接收請(qǐng)求參數(shù))


@Controller
@RequestMapping("emp")
public class EmpController {
/* 解耦合方式:獲取請(qǐng)求數(shù)據(jù),springmvc封裝好的 */
/*
* DispatcherServlet 會(huì)接收請(qǐng)求數(shù)據(jù),可以將請(qǐng)求數(shù)據(jù)進(jìn)行相關(guān)處理,然后傳遞給控制單元。
* *///1、接收普通參數(shù)//建議:盡量使用封裝類型,請(qǐng)求參數(shù)中沒有攜帶該參數(shù),自動(dòng)賦值為null//@RequestParam():請(qǐng)求參數(shù)中的名字 和 接收參數(shù)名不一致時(shí),使用該注解指定為請(qǐng)求參數(shù)名的名字@RequestMapping("a1")public String a1(@RequestParam("name") String uname, Integer age){System.out.println(uname);System.out.println(age);return "/index.jsp";}//2、使用JavaBean對(duì)象接收請(qǐng)求參數(shù)//注意:即使請(qǐng)求參數(shù)中沒有Emp的屬性,創(chuàng)建emp對(duì)象,傳遞到控制單元中//      使用JavaBean接收請(qǐng)求參數(shù)需要依賴于set方法@RequestMapping("a2")public String a2(Emp emp){System.out.println(emp);return "/index.jsp";}@RequestMapping("a3")public String a3(Emp emp, String name, String age){System.out.println(emp);System.out.println(name);System.out.println(age);return "/index.jsp";}//3、接收多個(gè)同名參數(shù)//數(shù)組:請(qǐng)求參數(shù)名和控制單元參數(shù)名相同即可直接接收//集合(List集合為例):必須通過@RequestParam執(zhí)行請(qǐng)求參數(shù)名//  如果為JavaBean中的屬性為L(zhǎng)ist集合接收同名多個(gè)屬性,不需要進(jìn)行額外處理。@RequestMapping("a4")public String a4(String[] strs){System.out.println(Arrays.toString(strs));return "/index.jsp";}@RequestMapping("a5")public String a5(@RequestParam("strs") List<String> strs){System.out.println(strs);return "/index.jsp";}@RequestMapping("a6")public String a6(Emp emp){System.out.println(emp);return "/index.jsp";}@RequestMapping("a7")//注意:默認(rèn)支持 yyyy/MM/dd 的日期格式//手動(dòng)指定接收的日期格式(@DateTimeFormat),一定手動(dòng)指定了接收的日期格式,默認(rèn)的日期格式不再生效public String a7(@DateTimeFormat(pattern = "yyyy-MM-dd") Date bir){System.out.println(bir);return "/index.jsp";}@RequestMapping("a8")public String a8(Emp emp){System.out.println(emp);return "/index.jsp";}/* 接收請(qǐng)求頭中的數(shù)據(jù) */@RequestMapping("a9")public String a9(@RequestHeader String accept){System.out.println(accept);return "/index.jsp";}@RequestMapping("a10")public String a10(@RequestHeader(value = "Accept-Language") String str){System.out.println(str);return "/index.jsp";}/* 向作用域?qū)ο笾写嬷?#xff08;request作用域) *///方式一:@RequestMapping("a11")public ModelAndView a11(){ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("/index.jsp");modelAndView.addObject("uname", "zs");return modelAndView;}//方式二:@RequestMapping("a12")public String a12(Map<String, Object> map){map.put("uname", "lsssss");return "/index.jsp";}//方式三:@RequestMapping("a13")public String a13(Model model){model.addAttribute("uname", "wwwwww");return "/index.jsp";}
}

七.@ResponseBody和@RequestBody注解

1.@ResponseBody

@ResponseBody:控制單元添加了該注解,不會(huì)執(zhí)行視圖解析器,將控制單元的返回值放入到響應(yīng)流直接響應(yīng)回到客戶端。

使用:

  • ????????默認(rèn):

????????????????1.控制單元只能返回String類型的數(shù)據(jù)。返回其他數(shù)據(jù)類型出現(xiàn)406狀態(tài)碼。

????????????????2.配合@RequestMapping(produces = "text/plain;charset=utf-8")設(shè)置響應(yīng)內(nèi)容類? ? ? ? ? ? ? ? ? ? ? ?型及編碼格式。

  • ????????引入了Jackson的依賴:

????????????????1.控制單元可以返回,JavaBean,數(shù)組[JavaBean], List<JavaBean>, Map,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? List<Map> 等類型數(shù)據(jù)。

? ? ? ? ? ? ? ? ? 2.springmvc默認(rèn)使用jack將控制單元的返回值變?yōu)閖son格式的字符串,設(shè)置響應(yīng)? ? ? ? ? ? ? ? ? ? ? ?內(nèi)容類型為application/json;charset=utf-8。

@RestController注解:效果和控制器中所有的方法都包含@ResponseBody注解一樣。

2.@RequestBody注解

將格式為?json ,xml 的客戶端請(qǐng)求參數(shù)轉(zhuǎn)換為 javabean。需要引入相依賴(Jackson)。

$.ajax({url:"testContentType",contentType:"application/json",// 修改請(qǐng)求內(nèi)容類型為JSONdata:'{"id":1,"name":"張三"}',// json格式傳多個(gè)數(shù)據(jù)必須有單引號(hào),沒有單引號(hào)無效type:"post",// 不能是GET類型請(qǐng)求success:function (data) {console.log(data);},dataType:"json"
});
@RequestMapping("/testContentType")
@ResponseBody
public People testContentType(@RequestBody People peo) {System.out.println(peo);return peo;
}

八.Spring MVC文件上傳和下載

1. 文件上傳

導(dǎo)入依賴:

<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>

在頁(yè)面中編寫文件上傳代碼:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body><form action="/upload" method="post" enctype="multipart/form-data">姓名:<input type="text" name="name"/><br/>頭像:<input type="file" name="photo"/><br/>地址:<input type="text" name="address"/><br/><input type="submit" value="提交"/><br/></form>
</body>
</html>

配置上傳文件解析器:

<!-- 文件上傳時(shí),必須配置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean><!--  限制上傳文件大小 -->
bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="1024"></property>
</bean>

編寫單元方法處理上傳請(qǐng)求:

    /*** 文件上傳控制單元方法實(shí)現(xiàn)* @param name 也可以使用JavaBean接收name的值* @param address 也可以使用JavaBean接收address的值* @param photo 名字必須和表單中文件域的name屬性值相同* @return* @throws IOException transferTo拋出的異常,可以使用try...catch處理異常。示例中為了讓代碼看起來簡(jiǎn)潔直接拋出了。*/@RequestMapping("/upload")
public String upload(String name, String address, MultipartFile photo,HttpServletRequest request) throws IOException {if(!photo.isEmpty()) {long timeMillis = System.currentTimeMillis();Random random = new Random();String fileName = timeMillis + "" + random.nextInt(1000);String oldName = photo.getOriginalFilename();String suffix = oldName.substring(oldName.lastIndexOf("."));// 獲取到當(dāng)前項(xiàng)目images目錄,發(fā)布到Tomcat后的絕對(duì)路徑。String realPath = request.getServletContext().getRealPath("/images");System.out.println(realPath);// 保存到當(dāng)前項(xiàng)目的images目錄中。photo.transferTo(new File(realPath,fileName + suffix));}return "/upload.jsp";
}

2. 文件下載

@RequestMapping("/download")
public void download(HttpServletRequest req, HttpServletResponse response, String filename) {try {// 因?yàn)槭荊ET請(qǐng)求,所以要解決請(qǐng)求參數(shù)中文亂碼問題String fileNameUtf8 = new String(filename.getBytes("iso-8859-1"), "utf-8");// 圖片名稱滿足固定格式String newFilenameUtf8 = "來自尚學(xué)堂的"+fileNameUtf8;String newFilenameISO = new String(newFilenameUtf8.getBytes("utf-8"),"iso-8859-1");// 此處是ISO-8859-1編碼的內(nèi)容response.setHeader("Content-Disposition", "attachment;filename=" + newFilenameISO);// 此處必須是UTF-8解決參數(shù)亂碼問題的名稱File file = new File(req.getServletContext().getRealPath("/images"), fileNameUtf8);FileInputStream fis = new FileInputStream(file);ServletOutputStream os = response.getOutputStream();IOUtils.copy(fis, os);} catch (IOException e) {e.printStackTrace();}
}

九.攔截器(重點(diǎn))

只有URL匹配到了控制單元,攔截器才能生效。

1. 使用攔截器

  • 創(chuàng)建攔截器:
public class MyInterceptor implements HandlerInterceptor {@Override
//執(zhí)行時(shí)機(jī):單元方法執(zhí)行之前。返回false表示攔截此次請(qǐng)求,返回true表示放行。public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("MyInterceptor.preHandle");return fasle;}
//執(zhí)行時(shí)機(jī):單元方法執(zhí)行之后,視圖解析器解析渲染視圖之前。@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor.postHandle");}//執(zhí)行時(shí)機(jī):視圖解析器解析渲染視圖完成之后。@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("MyInterceptor.afterCompletion");}
}
  • 配置攔截器:
 <!--配置攔截器作用:讓聲明的攔截器類生效完成單元方法請(qǐng)求的攔截使用:在springmvc.xml文件中使用<mvc:interceptors>標(biāo)簽聲明攔截的配置信息在<mvc:interceptors>標(biāo)簽下使用子標(biāo)簽完成攔截器的配置全局?jǐn)r截在<mvc:interceptors>直接聲明bean標(biāo)簽配置攔截器的bean,攔截所有的單元方法請(qǐng)求。局部攔截在<mvc:interceptors>標(biāo)簽下使用子標(biāo)簽<mvc:interceptor>來聲明局部攔截在<mvc:interceptor>標(biāo)簽下使用子標(biāo)簽配置攔截返回以及攔截器的bean<mvc:mapping path="/demo"/> 要攔截的范圍,可以聲明多個(gè)<bean id="mm" class="com.bjsxt.inter.MyInter"></bean> 攔截器
-->
<!--配置攔截器-->
<mvc:interceptors><!--配置攔截器的bean對(duì)象,攔截所有的單元方法--><bean class="com.bjsxt.interceptor.MyInterceptor2"></bean><!--配置具體的攔截器的bean極其攔截范圍,可以配置多個(gè)--><mvc:interceptor><mvc:mapping path="/myController/demo"/><!--配置攔截的單元方法的訪問路徑,第一個(gè)/表示項(xiàng)目根目錄,可以多個(gè)--><mvc:mapping path="/myController/kk/*"/><!--支持*通配符表示任意個(gè)數(shù)的任意字符,**表示路徑及子路徑--><bean class="com.bjsxt.interceptor.MyInterceptor"></bean><!--配置攔截器的bean對(duì)象,只在當(dāng)前mvc:interceptor內(nèi)有效--></mvc:interceptor>
</mvc:interceptors>

攔截器執(zhí)行順序總結(jié):

攔截器棧執(zhí)行順序:

2.攔截器和過濾器的區(qū)別(面試題)

  • 過濾器(Filter):由JavaEE提供的過濾器. 請(qǐng)求到達(dá)資源(servlet,頁(yè)面,css,js,img,...)之前都要經(jīng)過過濾器,資源響應(yīng)回到客戶端之前經(jīng)過過 濾器。
  • 攔截器(Interceptor):由SpringMVC提供的攔截器. 請(qǐng)求到到控制單元之前經(jīng)過攔截器(preHandle),控制單元執(zhí)行完成后經(jīng)過攔截器(postHandle),向頁(yè)面響應(yīng)完成,經(jīng)過攔截器(afterCompletion)。

區(qū)別:

  1. 來源不同

    攔截器是SpringMVC中的技術(shù),過濾器是Java EE中的技術(shù)。

  2. 生效位置不同

    攔截器是進(jìn)入DispatcherServlet后才能執(zhí)行,過濾器是進(jìn)入到Servlet容器前就可以觸發(fā)。

  3. 目標(biāo)不同

    攔截器攔截的目標(biāo)是HandlerMethod(控制單元,控制器方法),過濾器可以過濾所有的URL。

  4. 運(yùn)行機(jī)制不同

    攔截器是在HandlerMethod執(zhí)行前后和視圖處理完成后執(zhí)行,分為三部分。過濾器只能在目標(biāo)資源前后執(zhí)行。

  5. 接口中方法類型不同

    攔截器中的方法都是default方法,可以重寫也可以不重寫。過濾器中的方法都是abstract方法,如果當(dāng)前類不是抽象類,必須重寫。

  6. 上下文不同

    攔截器被Spring MVC管理,可以獲取到Spring容器中內(nèi)容。Filter被Tomcat管理,所以無法獲取Spring容器內(nèi)容。

十.視圖解析器(重點(diǎn))

1.ModelAndView:模型數(shù)據(jù)(存儲(chǔ)業(yè)務(wù)數(shù)據(jù))和視圖
? ? ? ? ? ? ? ?Model:模型數(shù)據(jù)(存儲(chǔ)模型層中查詢到的數(shù)據(jù))
? ? ? ? ? ? ? ?View: 視圖(頁(yè)面屬于視圖中的一種)
?2.控制單元執(zhí)行完成后,將控制單元返回的結(jié)果固定封裝為ModelAndView對(duì)象。

? ? Model中存儲(chǔ)了業(yè)務(wù)數(shù)據(jù),View通常存儲(chǔ)視圖名。最終目的:將Model中的業(yè)務(wù)數(shù)據(jù)通過? ? ? ??視圖 渲染 到客戶端。
? ? ? ? ? ?底層源碼:
? ? ? ? ? ? ? ?ModelAndView mv;
? ? ? ? ? ? ???mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
? ? ? ? ? ? ? 執(zhí)行控制單元,控制單元返回結(jié)果封裝為ModelAndView。

?3. 視圖解析器:ViewResolver(接口),根據(jù)ModelAndView對(duì)象中解析出的視圖名找到? ? ? ? ?對(duì)應(yīng)的視圖對(duì)象并返回。

以.jsp視圖為例:

? ??1.控制單元執(zhí)行后,執(zhí)行handle(processedRequest, response,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???mappedHandler.getHandler()),返回ModelAndView對(duì)象 (viewname為index.jsp)

? ? 2.獲取到ModelAndView后,執(zhí)行render(mv, request, response);?

? ? 3.在render方法中調(diào)用了view = resolveViewName(viewName, mv.getModelInternal(),? ? ? ? ? ? ? ?locale, request),獲取到視圖名。

? ??4.在resolveViewName(String viewName,Locale locale)方法中, 視圖解析器 根據(jù)視圖? ? ? ? ? 名找到對(duì)應(yīng)的視圖對(duì)象并返回。

? ? ? ? ?(1)默認(rèn)的使用的視圖解析器:InternalResourceViewResourceView。

? ? ? ? ?(2)?.jsp的視圖對(duì)象為:InternalResourceView。

????5.返回視圖對(duì)象后,調(diào)用view.render(mv.getModelInternal(), request, response)。實(shí)際完? ? ? ? ?成Model中的數(shù)據(jù)通過視圖響應(yīng)回到客戶端。

? ? 6. .jsp的InternalResourceView的視圖對(duì)象渲染時(shí):

? ? ? ? ? (1)將Model中的數(shù)據(jù)存儲(chǔ)到請(qǐng)求域?qū)ο笾小?/p>

? ? ? ? ? (2)將請(qǐng)求轉(zhuǎn)發(fā)到.jsp -> .java(獲取請(qǐng)求去對(duì)象中的數(shù)據(jù))-> .class -> 將結(jié)果輸出? ? ? ? ? ? ? ? ? ? ? ? 到客戶端。

十一.Spring MVC中組件

1. 組件介紹

DispatcherServlet被初始化的時(shí)候其底層內(nèi)部也會(huì)完成第2到第10個(gè)組件的初始化,調(diào)用其initStrategies方法來完成。

protected void initStrategies(ApplicationContext context) {this.initMultipartResolver(context);this.initLocaleResolver(context);this.initThemeResolver(context);this.initHandlerMappings(context);this.initHandlerAdapters(context);this.initHandlerExceptionResolvers(context);this.initRequestToViewNameTranslator(context);this.initViewResolvers(context);this.initFlashMapManager(context);
}

2.常用組件說明

  • DispatcherServlet:前端控制器。Spring MVC的入口,也是整個(gè)流程控制中心。其他組件 由DispatcherServlet統(tǒng)一調(diào)度,降低了組件和組件之間的耦合度。
  • MultipartResovler:多部分處理器。文件上傳時(shí)需要使用。
  • LocaleResolver:解決客戶端的區(qū)域和時(shí)區(qū)問題。
  • ThemeResolver:主題解析器。提供自定義布局。
  • HandlerMapping: 映射處理器。主要負(fù)責(zé)處理URL,并找到對(duì)應(yīng)的HandlerMethod(只是找到控制單元)。簡(jiǎn)單說就是找@RequestMapping注解中映射路徑是否有和URL匹配的。
  • HandlerAdapter:適配器。負(fù)責(zé)調(diào)用具體的HandlerMethod(調(diào)用并運(yùn)行)。
  • HandlerExceptionResovler:異常處理器。異常處理,根據(jù)不同異常返回視圖。
  • RequestToViewNameTranslator:從請(qǐng)求中獲取到視圖名稱。
  • ViewResovler:視圖解析器,負(fù)責(zé)解析字符串視圖名和物理視圖文件的。
  • FlashMapManager:主要用于存儲(chǔ)屬性的,本質(zhì)是一個(gè)Map。多用在重定向時(shí)。FlashMap在重定向之前存儲(chǔ),重定向之后刪除。
  • ModelAndView:模型和視圖。Spring MVC中提供的模型和視圖接口。
  • HandlerInterceptor:攔截器。攔截控制器資源的。

十二.SpringMVC運(yùn)行原理(常見面試題)

SpringMVC執(zhí)行流程:

?Tomcat啟動(dòng):

  • 監(jiān)聽到了ServletContext對(duì)象創(chuàng)建,加載Spring配置文件,創(chuàng)建Spring容器。
  • Tomcat啟動(dòng)后創(chuàng)建DispatcherServlet,DispatcherServlet初始化時(shí):

1.加載Springmvc配置文件,創(chuàng)建Springmvc容器。
2.初始化SpringMVC相關(guān)組件:MultipartResovler、HandlerMapping、? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?HandlerAdapterHandler、ExceptionResovler、ModelAndView、ViewResovler、? ? ? ? ? ? ? ? ? ?HandlerInterceptor。

  1. 客戶端向服務(wù)端發(fā)起請(qǐng)求,Spring MVC總體入口中央調(diào)度器DispatcherServlet進(jìn)行請(qǐng)求分發(fā)。

  2. 中央調(diào)度器DispatcherServlet把URL交給映射處理器HandlerMapping進(jìn)行解析URL。

  3. 映射處理器HandlerMapping將請(qǐng)求映射為HandlerExecutionChain處理器執(zhí)行鏈

    1. 可以為多個(gè)處理器攔截器HandlerInterceptor

    2. 處理器Handler對(duì)象(處理Controller)。

  4. 將處理器執(zhí)行鏈HandlerExecutionChain返回到中央調(diào)度器DispatcherServlet。

  5. DispatcherServlet根據(jù)返回的處理器執(zhí)行鏈HandlerExecutionChain獲得的處理器Handler,根據(jù)處理器Handler選擇處理器適配器HandlerAdapter。

  6. 執(zhí)行攔截器的preHandle()方法。

  7. 調(diào)用具體的Handler處理器(處理Controller),在填充Handler的入?yún)⑦^程中會(huì)執(zhí)行數(shù)據(jù)轉(zhuǎn)換、數(shù)據(jù)格式化、數(shù)據(jù)驗(yàn)證,調(diào)用具體的Controller完成處理功能,并創(chuàng)建ModelAndView對(duì)象。

  8. 執(zhí)行攔截器的postHandle()方法。

  9. 將ModelAndView對(duì)象返回到處理器適配器HandlerAdapter。

  10. 處理器適配器HandlerAdapter將ModelAndView對(duì)象返回到中央調(diào)度器DispatcherServlet。

  11. 中央調(diào)度器DispatcherServlet調(diào)用視圖解析器ViewResolver解析視圖。

  12. 將解析的視圖View對(duì)象返回到中央調(diào)度器DispatcherServlet。

  13. 渲染視圖,將視圖返回到中央調(diào)度器DispatcherServlet。

  14. 執(zhí)行攔截器afterCompletion()方法。

  15. 中央調(diào)度器DispatcherServlet響應(yīng)回到瀏覽器。

http://www.risenshineclean.com/news/58455.html

相關(guān)文章:

  • wordpress改變登錄地址seo網(wǎng)站診斷方案
  • 網(wǎng)站沒有備案時(shí)怎樣推廣自己的app
  • 做網(wǎng)站應(yīng)該注意些什么seo網(wǎng)站優(yōu)化軟件價(jià)格
  • 自己做微商想做個(gè)網(wǎng)站設(shè)計(jì)外包網(wǎng)站
  • 在環(huán)評(píng)備案網(wǎng)站上做登記后會(huì)怎么樣6精準(zhǔn)引流推廣
  • 聯(lián)通做網(wǎng)站百度推廣業(yè)務(wù)電話
  • 濱州做網(wǎng)站建設(shè)價(jià)格推廣方式有哪些?
  • amp for wordpress優(yōu)化網(wǎng)絡(luò)的軟件下載
  • 做界面的網(wǎng)站廣州網(wǎng)站優(yōu)化方案
  • wordpress 瀏覽量排序b2b網(wǎng)站推廣優(yōu)化
  • 做外貿(mào)的物流網(wǎng)站有哪些天津百度推廣排名優(yōu)化
  • 大胡子wordpress主題南昌seo優(yōu)化
  • 做外貿(mào)網(wǎng)站可以收付款嗎拉人注冊(cè)給傭金的app
  • 網(wǎng)站seo好學(xué)嗎營(yíng)銷方案案例范文
  • 現(xiàn)在哪些網(wǎng)站做外貿(mào)的好做拉新人拿獎(jiǎng)勵(lì)的app
  • 電子商務(wù)網(wǎng)站建設(shè)評(píng)估工具有哪些360搜索首頁(yè)
  • 西安網(wǎng)站建設(shè)市場(chǎng)虛擬主機(jī)搭建網(wǎng)站
  • 臨安建設(shè)投標(biāo)網(wǎng)站教育培訓(xùn)機(jī)構(gòu)有哪些
  • 新網(wǎng)站做seo地方網(wǎng)站建設(shè)
  • pc端移動(dòng)端網(wǎng)站開發(fā)太原網(wǎng)站快速排名提升
  • 濰坊網(wǎng)站制作 熊掌號(hào)臨汾網(wǎng)絡(luò)推廣
  • 為什么做網(wǎng)站更新注冊(cè)網(wǎng)站域名
  • 好域名做網(wǎng)站手機(jī)免費(fèi)發(fā)布信息平臺(tái)
  • 惠州市做網(wǎng)站網(wǎng)絡(luò)營(yíng)銷的內(nèi)涵
  • 汨羅網(wǎng)站建設(shè)制作網(wǎng)站平臺(tái)
  • 如何外貿(mào)seo網(wǎng)站建設(shè)外鏈工具
  • 博物館網(wǎng)站建設(shè)方案報(bào)價(jià)關(guān)鍵詞優(yōu)化分析工具
  • 公司宣傳冊(cè)設(shè)計(jì)與制作模板seo免費(fèi)課程
  • 在美國(guó)注冊(cè)一個(gè)網(wǎng)站 大陸做銷售網(wǎng)址推薦
  • 自己做網(wǎng)站現(xiàn)實(shí)么網(wǎng)站設(shè)計(jì)就業(yè)