一、Spring部分
1. Spring 的含義:
Spring
在不同的場景中表示不同的含義。早期的時候它被用來指代Spring Framework項目本身,這也是它一開始的含義。隨着時間的推移,在Spring Framework之上建立了其他Spring項目,比如SpringSecurity、SpringBoot、SpringCloud
。大部分情況下,當人們聊到Spring時,他們所說的 Spring 是 Spring 整個家族。
Spring 是一個輕量級的開源框架,是爲解決企業應用開發的複雜性而創建的。而在我的理解中,Spring 的主要就解決了兩件事情(當然它還解決了數據訪問、遠程調用、單元測試等問題),分別對應 Spring 的兩個設計思想 IOC 和 AOP:
- IOC 容器(解耦合):解決各種 new 對象的問題
- AOP (切面編程):把非業務範疇的功能,提取成一個切面,統一實現
2. 核心特性(Core)
- IoC 容器(IoC Container)
- Spring 事件(Events)
- 資源管理(Resources)
- 國際化(i18n)
- 校驗(Validation)
- 數據綁定(Data Binding)
- 類型轉換(Type Conversion)
- Spring 表達式(Spring Express Language)
- 面向切面編程(AOP)
這裏我們就可以解釋BeanFactory和ApplicationContext的區別了:
public interface BeanFactory {
// 根據bean名字查找
Object getBean(String name) throws BeansException;
// Bean延遲查找
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
// 判斷容器中有沒有這個名字的bean
boolean containsBean(String name);
// 判斷一個Bean是不是單例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
...
}
BeanFactory 看下去可以去做IOC當中的大部分事情,爲什麼還要去定義一個ApplicationContext 呢?
我們可以看一下ApplicationContext 的 結構圖
從圖中可以看到 ApplicationContext 它由BeanFactory接口派生而來,因而提供了BeanFactory所有的功能。除此之外context包還提供了以下的功能:
- MessageSource, 提供國際化的消息訪問
- 資源訪問,如URL和文件
- 事件傳播,實現了ApplicationListener接口的bean
- 載入多個(有繼承關係)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的web層
3. IOC
3.1 什麼是IOC?
IoC 全稱爲 Inversion of Control,翻譯爲 “控制反轉”,說白了,IOC 就是由 Spring IOC 容器來負責對象的生命週期和對象之間的關係。
所謂控制:就是對象的創建、初始化、銷燬。
- 創建對象:原來是 new 一個,現在是由 Spring 容器創建。
- 初始化對象:原來是對象自己通過構造器或者 setter 方法給依賴的對象賦值,現在是由 Spring 容器自動注入。
- 銷燬對象:原來是直接給對象賦值 null 或做一些銷燬操作,現在是 Spring 容器管理生命週期負責銷燬對象。
所謂反轉:
其實是反轉的控制權,前面提到是由 Spring 來控制對象的生命週期,那麼對象的控制就完全脫離了我們的控制,控制權交給了 Spring 。這個反轉是指:我們由對象的控制者變成了 IOC 的被動控制者。
總結:IOC 解決了繁瑣的對象生命週期的操作,解耦了我們的代碼。
3.2 IOC 能做什麼?
IOC 容器完美解決了耦合問題,甚至可以讓互不相關的對象產生注入關係。
在 IOC 模式下,你只需要設計良好的流程和依賴,定義出需要什麼,然後把控制權交給 Spring 即可。
3.3 IOC、DI、DL的區別
DI和DL:即依賴注入和依賴查找。
我們常說IOC和DI,卻忽略了DL,其實後兩者都是IOC的具體實現,在Spring中主要運用到的是DI,但並不代表沒有DL(依賴查找)。例如我們剛學Spring時寫的測試程序。
依賴注入主要分爲 手動模式 和 自動模式
- 手動模式:XML 資源配置元信息,Java 註解配置元信息,API 配置元信息
自動裝配的侷限性和缺點:
- 通過
property
和constructor-arg
進行依賴設定,這種顯式的設定始終會覆蓋自動裝配。你不能自動裝配簡單的屬性,例如基本類型,Strings
,和Classes
(以及這些簡單屬性的數組)。這種限制是由設計造成的。 - 自動裝配不如顯示裝配精確。如前表所述,儘量小心讓Spring避免去猜測模棱兩可的事情(知秋注:比如兩個相同類型的bean,也沒有其他特殊指定,Spring不知道該選擇哪個來進行注入操作),以免產生意想不到的結果。如果你不仔細,你的Spring所管理對象之間的關係不再明確。
- 裝配信息可能對從Spring容器中生成文檔的工具不可用。
- 容器內的多個bean definition可能與要自動裝配的setter方法或構造函數參數指明的類型匹配。對於數組,集合,或者
Map
實例,這就不是什麼問題了。然而,對於期望單值的依賴項來說,這種歧義性不能隨意的解決。如果沒有唯一的bean可用,將拋出一個異常。
總結:IOC 是一種設計思想。從 IOC 到 DI 和 DL ,就是從理論到實踐。程序把依賴交給容器,容器幫你管理依賴,這就是依賴注入的核心。依賴注入降低了開發的成本,提高了代碼複用率、軟件的靈活性
4. Spring常見註解:
@Autowired
自動導入對象到類中,被注入進的類同樣要被 Spring 容器管理比如:Service 類注入到 Controller 類中。
@Autowired和@Inject、@Resource,可以與@Qualifier或者@Name配合使用,防止多實例注入時出錯,以及值注入@Value。
註解 | 解析 | 用法 |
---|---|---|
@Autowired | 通過AutowiredAnnotationBeanPostProcessor類實現的依賴注入,默認是根據類型進行注入的,因此如果有多個類型一樣的Bean候選者,則需要限定其中一個候選者,否則將拋出異常。 | 可註釋在字段上,在方法上 |
@Inject | 作用與@Autowired一樣 | 可註釋在字段上,在方法上、構造器上 |
@Resource | 默認按照名稱進行裝配,名稱可以通過name屬性進行指定 | 可註釋在字段上,在方法上 |
@Qualifier | 限定描述符除了能根據名字進行注入,更能進行更細粒度的控制如何選擇候選者,可與@Autowired或者@Inject進行組合使用,進行精確注入 | 可註釋字段上,在方法上、參數上以及註解中 |
@Scope
作用域和生命週期
@Scope 聲明 Spring Bean 的作用域 ,四種常見的 Spring Bean 的作用域:
- singleton : 唯一 bean 實例,Spring 中的 bean 默認都是單例的。
- prototype : 每次請求都會創建一個新的 bean 實例。
- request : 每一次 HTTP 請求都會產生一個新的 bean,該 bean 僅在當前 HTTP request 內有效。
- session : 每一次 HTTP 請求都會產生一個新的 bean,該 bean 僅在當前 HTTP session 內有效。
具有4個作用域,以及生命週期過程處理@PostConstruct、@PreDestroy 。
註解 | 解析 | 用法 |
---|---|---|
@Scope | 具有4個作用域singleton,prototype,session,request,默認爲singleton單例模式 | 可註釋在Class創建時 |
@PostConstruct | 相當於init-method,使用在方法上,當Bean初始化時執行 | 可註釋在方法上 |
@PreDestroy | 相當於destory-method,使用在方法上,當Bean銷燬時執行 | 可註釋在方法上 |
案例:
@Service //組件注入,註明爲service組件
@Scope("prototype")//聲明Scope爲Prototype
public class UseFunctionService {
@Autowired //默認按type注入
@Qualifier("functionService") //精確注入
FunctionService functionService;
@Resource(name="baseDao")//默認按name注入,可以通過name和type屬性進行選擇性注入
private BaseDao baseDao;
@Inject
@Qualifier("userServiceImpl") //精確注入
public IUserService userService;
@PostConstruct//執行完構造函數後執行
public postConstruct(){
System.out.println("postConstruct");
}
@PreDestroy//在銷燬Bean前執行
public perDestroy(){
System.out.println("perDestroy");
}
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
public String SayHello(String word){
return functionService.sayHello(word);
}
}
@Component
,@Repository
,@Service
, @Controller
@component,而其餘 @Controller、@Service、@Repository都組合了@component註解,主要爲便於使用者Class組件進行歸類。默認加載IOC容器中的組件,容器啓動會調用無參構造器創建對象,再進行初始化賦值等操作
註解 | 解析 | 用法 |
---|---|---|
@Component | 組件註解,使用了該註解會基於註釋的配置和類路徑掃描時,會自動掃描並加載Class到ICO容器中 | 註釋在類上 |
@Controller | 應用在MVC層(控制層)DispatcherServlet會自動掃描註解了此註解的類,然後將web請求映射到註解了@RequestMapping的方法上 | 註釋在類上 |
@Service | 對應服務層,主要涉及一些複雜的邏輯,應用在service層(業務邏輯層) | 註釋在類上 |
@Repository | 對應持久層即 Dao 層,主要用於數據庫相關操作,應用在dao層(數據訪問層) | 註釋在類上 |
@Configuration
一般用來聲明配置類,可以使用 @Component
註解替代,不過使用Configuration
註解聲明配置類更加語義化。 主要區別在於Configuration
在Spring加載的時候,會被CGLib代理,裏面的@Bean不會出現重複實例化
官方有說到 ->
@Bean methods are to be declared within @Configuration classes, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management. This prevents the same @Bean method from accidentally being invoked through a regular Java call, which helps to reduce subtle bugs that can be hard to track down when operating in “lite” mode.
機器翻譯:在常見的場景中,@Bean方法將在@Configuration類中聲明,以確保始終使用“full”模式,並因此將交叉方法引用重定向到容器的生命週期管理。這可以防止通過常規Java調用意外調用相同的@Bean方法,這有助於減少在“lite”模式下操作時難以跟蹤的細微bug。
注:讀取配置信息@Value,事務註解@Transactional等,還有很多註解就不一一贅述了
二、SpringMVC部分
1. SpringMVC的含義
- 概念:SpringMVC是Spring框架中的一個分支,是基於Java實現MVC的輕量級Web框架
- 核心:Spring的web框架圍繞DispatcherServlet [ 調度Servlet ] 設計的。
總結: SpringMVC 本質上還是在使用Servlet處理,並在其基礎上進行了封裝簡化了開發流程,提高易用性、並使用程序邏輯結構變得更清晰
2. SpringMVC的執行流程
3. SpringMVC常見註解
@RequestMapping
處理常見的 HTTP 請求類型
5 種常見的請求類型:
- GET :請求從服務器獲取特定資源。舉個例子:
GET /users
(獲取所有用戶) - POST :在服務器上創建一個新的資源。舉個例子:
POST /users
(創建用戶) - PUT :更新服務器上的資源(客戶端提供更新後的整個資源)。舉個例子:
PUT /users/12
(更新編號爲 12 的用戶) - DELETE :從服務器刪除特定的資源。舉個例子:
DELETE /users/12
(刪除編號爲 12 的用戶) - PATCH :更新服務器上的資源(客戶端提供更改的屬性,可以看做作是部分更新),使用的比較少。
註解 | 解析 |
---|---|
@GetMapping | @GetMapping("users") 等價於@RequestMapping(value="/users",method=RequestMethod.GET) |
@PostMapping | @PostMapping("users") 等價於@RequestMapping(value="/users",method=RequestMethod.POST) |
@PutMapping | @PutMapping("/users/{userId}") 等價於@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT) |
@DeleteMapping | @DeleteMapping("/users/{userId}") 等價於@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE) |
前後端傳值@PathVariable
和 @RequestParam
@PathVariable
用於獲取路徑參數,@RequestParam
用於獲取查詢參數。
舉個簡單的例子:
@GetMapping("/users/{userId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
@PathVariable("userId") Long userId,
@RequestParam(value = "type", required = false) String type){
...
}
如果我們請求的 url 是:/users/{123456}/teachers?type=web
那麼我們服務獲取到的數據就是:userIDd=123456,type=web
。
@RequestBody
用於讀取 Request 請求(可能是 POST,PUT,DELETE,GET 請求)的 body 部分並且Content-Type 爲 application/json 格式的數據,接收到數據之後會自動將數據綁定到 Java 對象上去。系統會使用HttpMessageConverter
或者自定義的HttpMessageConverter
將請求的 body 中的 json 字符串轉換爲 java 對象。
@RestController
@ResponseBody
註解的作用是將controller的方法返回的對象通過適當的轉換器轉換爲指定的格式之後,寫入到response對象的body區,通常用來返回JSON數據或者是XML數據,常見於前後端分離項目。
而@RestController
註解是@Controller和
@ResponseBody
的合集,表示這是個控制器 bean,並且是將函數的返回值直 接填入 HTTP 響應體中,是 REST 風格的控制器。
JSR303 一套JavaBean參數校驗的標準
它定義了很多常用的校驗註解 一些常用的字段驗證的註解
@NotEmpty
被註釋的字符串的不能爲 null 也不能爲空@NotBlank
被註釋的字符串非 null,並且必須包含一個非空白字符@Null
被註釋的元素必須爲 null@NotNull
被註釋的元素必須不爲 null@AssertTrue
被註釋的元素必須爲 true@AssertFalse
被註釋的元素必須爲 false@Pattern(regex=,flag=)
被註釋的元素必須符合指定的正則表達式@Email
被註釋的元素必須是 Email 格式。@Min(value)
被註釋的元素必須是一個數字,其值必須大於等於指定的最小值@Max(value)
被註釋的元素必須是一個數字,其值必須小於等於指定的最大值@DecimalMin(value)
被註釋的元素必須是一個數字,其值必須大於等於指定的最小值@DecimalMax(value)
被註釋的元素必須是一個數字,其值必須小於等於指定的最大值@Size(max=, min=)
被註釋的元素的大小必須在指定的範圍內
三、mybatis部分
1. mybatis的含義
MyBatis
的前身是 iBatis
,iBatis是 Apache 軟件基金會下的一個開源項目。2010 年該項目從Apache 基金會遷出,並改名爲MyBatis。同期,iBatis停止維護。 MyBatis是一種半自動化的Java持久層框架,其通過註解或XML 的方式將對象和SQL 關聯起來。之所以說它是半自動的,是因爲和Hibernate 等一些可自動生成SQL的ORM框架相比,使用MyBatis需要用戶自行維護SQL,維護SQL 的工作比較繁瑣,但也有好處。比如我們可控制SQL邏輯,可對其進行優化,以提高效率。
2. mybatis的核心部分
2.1 MyBatis配置XML文件的層次結構
<?xml version="1. 0" encoding="UTF-8"?>
<configuration> <!--配置 -->
<properties/> <!--屬性-->
<settings/> <!--設置-->
<typeAliases/> <!--類型命名-->
<typeHandlers/> <!--類型處理器-->
<objectFactory/> <!--對象工廠-->
<plugins/> <!--插件-->
<environments> <!--配置環境-->
<environment> <!--環境變量 -->
<transactionManager/> <!--事務管理器-->
<dataSource/> <!-- 數據源-->
</environment>
</environments>
<databaseIdProvider/> <!--數據庫廠商標識-->
<mappers/> <!--映射器-->
</configuration>
例舉幾個,不一一解釋了
- properties是一個配置屬性的元素,讓我們能在配置文件的上下文中使用它。
- 別名(typeAliases) 是一個指代的名稱。因爲我們遇到的類全限定名過長,所以我們希望用一個簡短的名稱去指代它,而這個名稱可以在MyBatis 上下文中使用。
- mappers常見有如下幾種方法引入映射器
- 文件路徑引入
- 包名引入
- 類註冊引入
2.2 MyBatis的映射器
常見元素如下:
着重說一下resultMap吧,這也是mybtais裏最複雜的元素,它的作用是定義映射規則,級聯的更新,定製類型轉化器。
<resultMap id="" type="">
<constructor></constructor>
<id></id> <!-- id代表resultMap的主鍵,而result代表其屬性 -->
<result></result>
<association property=""></association> <!-- 一對一映射 -->
<collection property=""></collection> <!-- 一對多映射 -->
</resultMap>
constructor:constructor主要是用來配置構造方法,默認情況下mybatis會調用實體類的無參構造方法創建一個實體類,然後再給各個屬性賦值,但是有的時候我們可能爲實體類生成了有參的構造方法,並且也沒有給該實體類生成無參的構造方法,這個時候如果不做特殊配置,resultMap在生成實體類的時候就會報錯,因爲它沒有找到無參構造方法。
association 和 collection:是mybatis支持級聯的一部分,我們知道在級聯中有一對一、一對多、多對多等關係,association主要是用來解決一對一關係的,collection主要是用來解決一對多關係的
2.3 Mybtais操作案例
public class SqlSessionUtils {
private SqlSessionUtils(){}
// 配置文件
public static final String resource = "mybatis-config.xml";
/**
* SqlSession是通過SqlSessionFactory來構造的,相當於維護一個連接池,當我們不停的進行查詢的時候, * 由於沒有關閉連接,導致與數據庫的連接數量達到了一個上限
*/
public static SqlSession getDefaultSqlSession() throws IOException {
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory.openSession();
}
/**
* SqlSessionManager通過動態代理技術+線程本地變量,升級了DefaultSqlSession的使用。
* 解決了DefaultSqlSession自動關閉和線程安全問題
* @return
* @throws IOException
*/
public static SqlSession getSqlSessionManage() throws IOException {
InputStream inputStream = Resources.getResourceAsStream(resource);
return SqlSessionManager.newInstance(inputStream);
}
}
@Test
public void testUpdateUserInfo() throws IOException {
SqlSession sqlSession = SqlSessionUtils.getDefaultSqlSession();
UserInfo userInfo = new UserInfo();
userInfo.setId(3);
userInfo.setUserName("測試修改");
userInfo.setPassword("111111");
userInfo.setRegDate(new Timestamp(Instant.now().toEpochMilli()));
// sqlSession.update("com.changda.mapper.UserInfoMapper.updateUserInfo");
UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
System.out.println(mapper.updateUserInfo(userInfo));
sqlSession.commit();
}
@Test
public void testUpdateUserInfo() throws IOException {
SqlSession sqlSession = SqlSessionUtils.getSqlSessionManage();
UserInfo userInfo = new UserInfo();
userInfo.setId(3);
userInfo.setUserName("測試修改");
userInfo.setPassword("111111");
userInfo.setRegDate(new Timestamp(Instant.now().toEpochMilli()));
UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
System.out.println(mapper.updateUserInfo(userInfo));
}
3.Mybatis中的Dao接口和XML文件裏的SQL是如何建立關係的?
- 解析XML: 初始化SqlSessionFactoryBean會將mapperLocations路徑下所有的XML文件進行解析
- 創建SqlSource: Mybatis會把每個SQL標籤封裝成SqlSource對象,可以爲動態SQL和靜態SQL
- 創建MappedStatement: XML文件中的每一個SQL標籤就對應一個MappedStatement對象 ,並由 Configuration解析XML
- Dao接口代理: Spring中的FactoryBean 和 JDK動態代理返回了可以注入的一個Dao接口的代理對象
- 執行: 通過statement全限定類型+方法名拿到MappedStatement 對象,然後通過執行器Executor去執行具體SQL
四、SSM整合
第一步:導入相應的jar包
<properties>
<spring.version>5.1.8.RELEASE</spring.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- mybatis 包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--mybatis spring 插件 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- mysql連接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- slf4j日誌包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
第二步:寫配置文件,將配置文件區分開
例舉常見的一些xml配置,這裏Spring3.0以後其實開始提倡JavaConfig的方式實現去XML配置,大家也不需要全部都記得,尤其Spring5.x版本之後,可以通過導入tomcat的內嵌jar包形式實現零xml配置啓動,畢竟緊跟技術潮流嘛。
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置IOC註解解析器 -->
<context:component-scan base-package="com.zl.controller" />
<!-- 配置MVC註解解析器 -->
<mvc:annotation-driven/>
<!-- 啓動對@AspectJ註解的支持 -->
<aop:aspectj-autoproxy/>
<!-- 釋放靜態資源 -->
<mvc:default-servlet-handler/>
<!-- 配置視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置邏輯視圖的前綴 -->
<property name="prefix" value="/views/" />
<!-- 配置邏輯視圖的後綴 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
</beans>
applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加載配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 數據庫連接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1"/>
<property name="minIdle" value="1"/>
<property name="maxActive" value="10"/>
<!-- 配置獲取連接等待超時的時間 -->
<property name="maxWait" value="10000"/>
<!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="testWhileIdle" value="true"/>
<!-- 這裏建議配置爲TRUE,防止取到的連接不可用 -->
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="false"/>
<!-- 添加此處作用是爲了在SQL監控頁面顯示sql執行語句,不配置不顯示 -->
<property name="filters" value="stat" />
</bean>
<!-- 配置 SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 數據庫連接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加載 mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml" />
<!-- 自動掃描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapping/*.xml"></property>
</bean>
<!-- 配置 Mapper掃描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置 Mapper掃描包 -->
<property name="basePackage" value="com.zl.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
</beans>
application-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置 service掃描 -->
<context:component-scan base-package="com.zl.service.impl" />
<!-- 配置 線程池 -->
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>
<!-- 掃描切點類組件 -->
<context:component-scan base-package="com.zl.aop" />
</beans>
applicationContext-trans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 數據源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!--事務增強-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--事務屬性定義-->
<tx:attributes>
<tx:method name="list*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="validate*" read-only="true"/>
<tx:method name="count*" read-only="true"/>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 切面 匹配所有com.zl.service.impl包下的任意類和方法-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.zl.service.impl.*.*(..))" />
</aop:config>
</beans>
第三步:配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>FruitSales</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<!-- 使用監聽器加載 Spring配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置 spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*.xml</param-value>
</context-param>
<!-- 配置 SrpingMVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<!-- 標記容器在啓動的時候就加載這個servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 配置所有以 /結尾的請求進入 SpringMVC -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- post亂碼過濾器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
第四步:寫測試用例
能看到helloWord就算搭建完成了
@Controller
public class UserInfoController {
@RequestMapping("/login")
public String login(){
System.out.println("helloword!");
return "index";
}
}