1、SpringMVC的工作原理?
● 用戶向服務器發送請求,請求被springMVC前端控制器DispatchServlet捕獲;
● DispatcherServle對請求URL進行解析,得到請求資源標識符(URL),然后根據該URL調用HandlerMapping將請求映射到處理器HandlerExcutionChain;
● DispatchServlet根據獲得Handler選擇一個合適的HandlerAdapter適配器處理;
● Handler對數據處理完成以后將返回一個ModelAndView對象給DisPatchServlet;
● Handler返回的ModelAndView只是一個邏輯視圖并不是一個正式的視圖,DispatcherSevlet通過ViewResolver試圖解析器將邏輯視圖轉化為真正的視圖View;
● DispatcherServle通過model解析出ModelAndView()中的參數進行解析最終展現出完整的view并返回給客戶端;
2、SpringMVC常用注解都有哪些?
● @RequestMapping用于請求url映射。
● @RequestBody注解實現接收http請求的json數據,將json數據轉換為java對象。
● @ResponseBody注解實現將controller方法返回對象轉化為json響應給客戶。
我們在項目中一般會在springmvc.xml中通過開啟<mvc:annotation-driven>來實現注解處理器和適配器的開啟。
解決post請求亂碼:我們可以在web.xml里邊配置一個CharacterEncodingFilter過濾器。設置為utf-8.解決get請求的亂碼:有兩種方法。對于get請求中文參數出現亂碼解決方法有兩個:
● 修改tomcat配置文件添加編碼與工程編碼一致。
● 另 外 一 種 方 法 對 參 數 進 行 重 新 編 碼 String userName = new String(request.getParameter(“userName”).getBytes(“ISO8859-1”),“utf-8”);
Spring是一個開源框架,為簡化企業級應用開發而生。Spring可以是使簡單的JavaBean實現以前只有EJB才能實現的功能。Spring是一個IOC和AOP容器框架。
● Spring容器的主要核心是:
控制反轉(IOC),傳統的java開發模式中,當需要一個對象時,我們會自己使用new或者getInstance等直接或者間接調用構造方法創建一個對象。而在spring開發模式中,spring容器使用了工廠模式為我們創建了所需要的對象,不需要我們自己創建了,直接調用spring提供的對象就可以了,這是控制反轉的思想。
依賴注入(DI),spring使用JavaBean對象的set方法或者帶參數的構造方法為我們在創建所需對象時將其屬性自動設置所需要的值的過程,就是依賴注入的思想。
面向切面編程(AOP),在面向對象編程(oop)思想中,我們將事物縱向抽成一個個的對象。而在面向切面編程中,我們將一個個的對象某些類似的方面橫向抽成一個切面,對這個切面進行一些如權限控制、事物管理,記錄日志等公用操作處理的過程就是面向切面編程的思想。AOP底層是動態代理,如果是接口采用JDK動態代理,如果是類采用CGLIB方式實現動態代理
● 單例模式——spring中兩種代理方式,若目標對象實現了若干接口,spring使用jdk的java.lang.reflect.Proxy類代理。若目標兌現沒有實現任何接口,spring使用CGLIB庫生成目標類的子類。單例模式——在spring的配置文件中設置bean默認為單例模式。
● 模板方式模式——用來解決代碼重復的問題。比如:RestTemplate、JmsTemplate、JpaTemplate
● 前端控制器模式——spring提供了前端控制器DispatherServlet來對請求進行分發。
● 試圖幫助(viewhelper)——spring提供了一系列的JSP標簽,高效宏來幫助將分散的代碼整合在試圖中。
● 依賴注入——貫穿于BeanFactory/ApplacationContext接口的核心理念。
● 工廠模式——在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,并且是通過使用同一個接口來指向新創建的對象。Spring中使用beanFactory來創建對象的實例。
Spring在2.5版本以后開始支持注解的方式來配置依賴注入。可以用注解的方式來代替xml中bean的描述。注解注入將會被容器在XML注入之前被處理,所以后者會覆蓋掉前者對于同一個屬性的處理結果。
注解裝配在spring中默認是關閉的。所以需要在spring的核心配置文件中配置一下才能使用基于注解的裝配模式。配置方式如下:<context:annotation-config/>
● 常用的注解:
@Required:該注解應用于設值方法。
@Autowired:該注解應用于有值設值方法、非設值方法、構造方法和變量。
@Qualifier:該注解和@Autowired搭配使用,用于消除特定bean自動裝配的歧義。
● bean定義:在配置文件里面用<bean></bean>來進行定義。
● bean初始化:有兩種方式初始化:
1、在配置文件中通過指定init-method屬性來完成。
2、實現org.springframwork.beans.factory.InitializingBean接口。
● bean調用:有三種方式可以得到bean實例,并進行調用
● bean銷毀:銷毀有兩種方式:
1、使用配置文件指定的destroy-method屬性。
2、實現org.springframwork.bean.factory.DisposeableBean。
● 核心容器:包括Core、Beans、Context、EL模塊。
1、Core模塊:封裝了框架依賴的最底層部分,包括資源訪問、類型轉換及一些常用工具類。
2、Beans模塊:提供了框架的基礎部分,包括反轉控制和依賴注入。其中BeanFactory是容器核心,本質是“工廠設計模式”的實現,而且無需編程實現“單例設計模式”,單例完全由容器控制,而且提倡面向接口編程,而非面向實現編程;所有應用程序對象及對象間關系由框架管理,從而真正把你從程序邏輯中把維護對象之間的依賴關系提取出來,所有這些依賴關系都由BeanFactory來維護。
3、Context模塊:以Core和Beans為基礎,集成Beans模塊功能并添加資源綁定、數據驗證、國際化、JavaEE支持、容器生命周期、事件傳播等;核心接口是ApplicationContext。
4、EL模塊:提供強大的表達式語言支持,支持訪問和修改屬性值,方法調用,支持訪問及修改數組、容器和索引器,命名變量,支持算數和邏輯運算,支持從Spring容器獲取Bean,它也支持列表投影、選擇和一般的列表聚合等。
● AOP、Aspects模塊:
1、AOP模塊:SpringAOP模塊提供了符合AOPAlliance規范的面向方面的編程(aspect-orientedprogramming)實現,提供比如日志記錄、權限控制、性能統計等通用功能和業務邏輯分離的技術,并且能動態的把這些功能添加到需要的代碼中;這樣各專其職,降低業務邏輯和通用功能的耦合。
2、Aspects模塊:提供了對AspectJ的集成,AspectJ提供了比SpringASP更強大的功能。數據訪問/集成模塊:該模塊包括了JDBC、ORM、OXM、JMS和事務管理。
3、事務模塊:該模塊用于Spring管理事務,只要是Spring管理對象都能得到Spring管理事務的好處,無需在代碼中進行事務控制了,而且支持編程和聲明性的事務管理。
4、JDBC模塊:提供了一個JBDC的樣例模板,使用這些模板能消除傳統冗長的JDBC編碼還有必須的事務控制,而且能享受到Spring管理事務的好處。
5、ORM模塊:提供與流行的“對象-關系”映射框架的無縫集成,包括Hibernate、JPA、MyBatis等。而且可以使用Spring事務管理,無需額外控制事務。
6、OXM模塊:提供了一個對Object/XML映射實現,將java對象映射成XML數據,或者將XML數據映射成java對象,Object/XML映射實現包括JAXB、Castor、XMLBeans和XStream。
7、JMS模塊:用于JMS(JavaMessagingService),提供一套“消息生產者、消息消費者”模板用于更加簡單的使用JMS,JMS用于用于在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。
8、Web/Remoting模塊:Web/Remoting模塊包含了Web、Web-Servlet、Web-Struts、Web-Porlet模塊。
9、Web模塊:提供了基礎的web功能。例如多文件上傳、集成IoC容器、遠程過程訪問(RMI、Hessian、Burlap)以及WebService支持,并提供一個RestTemplate類來提供方便的Restfulservices訪問。
10、Web-Servlet模塊:提供了一個SpringMVCWeb框架實現。SpringMVC框架提供了基于注解的請求資源注入、更簡單的數據綁定、數據驗證等及一套非常易用的JSP標簽,完全無縫與Spring其他技術協作。
11、Web-Struts模塊:提供了與Struts無縫集成,Struts1.x和Struts2.x都支持
12、Test模塊:Spring支持Junit和TestNG測試框架,而且還額外提供了一些基于Spring的測試功能,比如在測試Web框架時,模擬Http請求的功能。
10、Spring能幫我們做什么?
● Spring能幫我們根據配置文件創建及組裝對象之間的依賴關系。
● Spring根據配置文件來進行創建及組裝對象間依賴關系,只需要改配置文件即可
● Spring面向切面編程能幫助我們無耦合的實現日志記錄,性能統計,安全控制。
● Spring面向切面編程能提供一種更好的方式來完成,一般通過配置方式,而且不需要在現有代碼中添加任何額外代碼,現有代碼專注業務邏輯。
● Spring能非常簡單的幫我們管理數據庫事務。
● 采用Spring,我們只需獲取連接,執行SQL,其他事物相關的都交給Spring來管理了。
● Spring還能與第三方數據庫訪問框架(如Hibernate、JPA)無縫集成,而且自己也提供了一套JDBC訪問模板,來方便數據庫訪問。
● Spring還能與第三方Web(如Struts、JSF)框架無縫集成,而且自己也提供了一套SpringMVC框架,來方便web層搭建。
● Spring能方便的與JavaEE(如JavaMail、任務調度)整合,與更多技術整合(比如緩存框架)。
聲明式事務管理的定義:用在Spring配置文件中聲明式的處理事務來代替代碼式的處理事務。這樣的好處是,事務管理不侵入開發的組件,具體來說,業務邏輯對象就不會意識到正在事務管理之中,事實上也應該如此,因為事務管理是屬于系統層面的服務,而不是業務邏輯的一部分,如果想要改變事務管理策劃的話,也只需要在定義文件中重新配置即可,這樣維護起來極其方便。
基于TransactionInterceptor的聲明式事務管理:兩個次要的屬性:transactionManager,用來指定一個事務治理器,并將具體事務相關的操作請托給它;其他一個是Properties類型的transactionAttributes屬性,該屬性的每一個鍵值對中,鍵指定的是方法名,方法名可以行使通配符,而值就是表現呼應方法的所運用的事務屬性。
<beans>
......
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="bankServiceTarget"
class="footmark.spring.core.tx.declare.origin.BankServiceImpl">
<property name="bankDao" ref="bankDao"/>
</bean>
<bean id="bankService"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="bankServiceTarget"/>
<property name="interceptorNames">
<list>
<idref bean="transactionInterceptor"/>
</list>
</property>
</bean>
</beans>
基于 TransactionProxyFactoryBean 的聲明式事務管理:設置配置文件與先前比照簡化了許多。我們把這類設置配置文件格式稱為 Spring 經典的聲明式事務治理。
<beans>
......
<bean id="bankServiceTarget"
class="footmark.spring.core.tx.declare.classic.BankServiceImpl">
<property name="bankDao" ref="bankDao"/>
</bean>
<bean id="bankService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="bankServiceTarget"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
基于 <tx> 命名空間的聲明式事務治理:在前兩種方法的基礎上,Spring 2.x 引入了 <tx> 命名空間, 連絡行使 <aop> 命名空間,帶給開發人員設置配備聲明式事務的全新體驗。
<beans>
......
<bean id="bankService"
class="footmark.spring.core.tx.declare.namespace.BankServiceImpl">
<property name="bankDao" ref="bankDao"/>
</bean>
<tx:advice id="bankAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="bankPointcut" expression="execution(* *.transfer(..))"/>
<aop:advisor advice-ref="bankAdvice" pointcut-ref="bankPointcut"/>
</aop:config>
......
</beans>
基于 @Transactional 的聲明式事務管理:Spring 2.x 還引入了基于 Annotation 的體式格式,具體次要觸及@Transactional 標注。@Transactional 可以浸染于接口、接口方法、類和類方法上。算作用于類上時,該類的一切public 方法將都具有該類型的事務屬性。
@Transactional(propagation = Propagation.REQUIRED)
public boolean transfer(Long fromId, Long toId, double amount) {
return bankDao.transfer(fromId, toId, amount);
}
編程式事務管理的定義:在代碼中顯式挪用 beginTransaction()、commit()、rollback()等事務治理相關的方法, 這就是編程式事務管理。Spring 對事物的編程式管理有基于底層 API 的編程式管理和基于 TransactionTemplate 的編程式事務管理兩種方式。
基于底層 API 的編程式管理:憑證 PlatformTransactionManager 、 TransactionDefinition 和TransactionStatus 三個焦點接口,來實現編程式事務管理。
public class BankServiceImpl implements BankService {
private BanckDao bankDao;
private TransactionDefinition txDefinition;
private PlatformTransactionManager txManager;
public boolean transfer(Long fromId, Long toId, double amount) {
TransactionStatus txStatus = txManager.getTransaction(txDefinition);
boolean result = false;
try {
result = bankDao.transfer(fromId, toId, amount);
txManager.commit(txStatus);
} catch (Exception e) {
result = false;
txManager.rollback(txStatus);
System.out.println("Transfer Error!");
}
return result;
}
}
基于 TransactionTemplate 的編程式事務管理:為了不損壞代碼原有的條理性,避免出現每一個方法中都包括相同的啟動事物、提交、回滾事物樣板代碼的現象,spring 提供了 transactionTemplate 模板來實現編程式事務管理。
public class BankServiceImpl implements BankService {
private BankDao bankDao;
private TransactionTemplate transactionTemplate;
public boolean transfer(final Long fromId, final Long toId, final double amount) {
return (Boolean) transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Object result;
try {
result = bankDao.transfer(fromId, toId, amount);
} catch (Exception e) {
status.setRollbackOnly();
result = false;
System.out.println("Transfer Error!");
}
return result;
}
});
}
}
編程式事務與聲明式事務的區別:
編程式事務是自己寫事務處理的類,然后調用。
聲明式事務是在配置文件中配置,一般搭配在框架里面使用。