Spring+SpringMVC+Mybatis知識點複習【SSM框架複習筆記】

一、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包還提供了以下的功能:

  1. MessageSource, 提供國際化的消息訪問
  2. 資源訪問,如URL和文件
  3. 事件傳播,實現了ApplicationListener接口的bean
  4. 載入多個(有繼承關係)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的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 配置元信息
    在這裏插入圖片描述
    在這裏插入圖片描述
    自動裝配的侷限性和缺點:
  • 通過 propertyconstructor-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在生成實體類的時候就會報錯,因爲它沒有找到無參構造方法。

associationcollection:是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";
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章