1. 程式人生 > >01 Spring與SpringMVC回顧

01 Spring與SpringMVC回顧

文章目錄

前言

SpringBoot本身沒有增加任何新的技術,其是對Spring開發方式的一種簡化。

Spring的出現,本身是為了簡化JavaEE的開發。

可是隨著Spring體系的不斷壯大,Spring本身也被各種配置所拖累,有戲言稱:Spring開發就是一本java一半xml。

SpringBoot則利用Spring4開始提供的條件註解,大大簡化了Spring專案的開發。

現在的開發人員是幸福的,從語言到工具鏈,以及現在的網路環境和學習環境,只要想學,就能有所收穫。

本文梳理一下Spring和SpringMVC的核心功能,並不對基礎概念進行解釋。建議在學習Spring之前,小夥伴需要對Spring有所瞭解。

Spring核心

Spring框架設計原則

Spring的出現了為了簡化JavaEE開發,其在設計過程中遵循了一些基礎原則

  • 使用POJO進行輕量級和最小侵入式開發
  • 通過依賴注入和基於介面程式設計實現鬆耦合
  • 通過AOP和預設習慣進行宣告式程式設計
  • 使用AOP和 模板減少模式化程式碼

控制反轉與依賴注入

名詞解釋

  • 什麼是控制反轉

在編寫Java程式碼時,最長做的操作可能就是獲取一個物件了,在原始階段,我們可能使用new關鍵字建立一個物件,當然,也有通過工廠模式獲取物件的。

但不管怎麼說,這個物件是我們自己來的。

而在Spring中,我們是在編寫一個個元件,元件編寫完畢後交給Spring管理,在需要用到的地方只要一聲,由Spring負責物件的初始化。

將物件由原先自己建立,改變為使用Spring管理的過程,這就是控制反轉

  • 什麼是依賴注入

Spring根據我們的說明,將合適的物件交給我們進行使用,這個就是依賴注入。

核心註解

在控制反轉與依賴注入過程中,我們會用到一些註解

宣告Bean:@Component、@Service、@Repository、@Controller

注入Bean:@Autowired、@Inject、@Resource

@Configuration:聲明當前類是一個配置類

@ComponentScan:掃描Bean,將被掃描到的Bean初始化後納入Spring容器進行管理

面向切面程式設計

面向過程和麵向物件,是我們比較熟悉的兩種程式設計正規化。

面向切面也一樣,也是一種程式設計正規化。

其不是對其它程式設計正規化的顛覆,只是一個有益的補充。有其合適的適用場景。

舉個例子,我們希望在特定方法呼叫前和呼叫後,將呼叫的方法引數和返回值進行答應。這個時候使用AOP做就非常方便。否則我們就需要手動在方法內部進行日誌的列印。

SpEL表示式

  • 將固定的字串注入給成員變數
@Value("普通字串注入")
private String str;
  • 使用SpEL表示式獲取系統屬性進行注入
@Value("#systemProperties['os.name']")
private String osName;
  • 使用SpEL表示式生成一個隨機數
@Value("#{T(java.lang.Math).random()*100.0}")
private double randomNumber;
  • 注入其他Bean的屬性
@Value("#{demoService.property}")
  • 注入檔案
@Value("classpath:com/ist/a.txt")
private Resource resource;
  • 注入網路資源
@Value("http://www.baidu.com")
private Resource resource;
  • 注入屬性檔案的鍵值
@Value("${book.name}")
private String st;
  • 注入配置檔案
@Autowired
private Environment env;

將當前類使用的配置檔案注入給env,呼叫env.getProperty("book.name)"),就能夠獲取資料

Bean的生命週期

有時候在Bean初始化和銷燬的時候需要做一些事情

  • 在使用@Bean註解的時候,通過initMethod和destoryMethod屬性指定
  • 在Bean中,使用@PostConstruct(在建構函式執行完後執行)和@PreDestory
    ​ (在Bean銷燬前執行)如果使用第二種方式,那麼需要新增JSR-250支援
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>jsr250-api</artifactId>
    <version>1.0</version>
</dependency>

一般使用initMethod和destoryMethod就行了

非同步方法

使用多執行緒,實現方法的非同步呼叫

1、配置一個執行緒池

package cfg.spring;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
 * Created by nbcoolkid on 2017-05-20.
 */
@Configuration
@EnableAsync
public class TaskExecConf implements AsyncConfigurer{
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(10);
        threadPoolTaskExecutor.setQueueCapacity(25);
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
@Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

2、在配置類中使用@EnableAsync開啟對非同步任務的支援

在執行Bean中使用@Async註解宣告其是一個非同步任務,如果標註在類上,說明這個類的所有方法都是非同步的

定時任務

對於一些簡單的定時任務,Spring也有自己的實現

使用方法:

1、在配置類上使用@EnableScheduling開啟支援

2、在任務方法上使用@Scheduled,使用core表示式設定時間

package org.zln.spb.task;
import org.springframework.scheduling.annotation.Scheduled;
import org.zln.spb.ann.Task;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
@Task
public class Demo01Task {
    @Scheduled(cron = "0/5 * * * * ? ")
    public void showH() {
        System.out.println("定時任務執行---");
    }
}

這裡的@Task註解是一個自定義註解

package org.zln.spb.ann;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Task {
    String value() default "";
}

package org.zln.spb.task;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
@Configuration
@EnableScheduling
@ComponentScan
public class TaskConfig {
}
package org.zln.spb.task;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * Created by nbcoolkid on 2017-10-17.
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TaskConfig.class);
        Thread.sleep(1000 * 3600);
    }
}

小結

Spring的內容當然不止這麼些,但是有些內容在SpringBoot中會深入講解,有些內容已經過時,這裡就不再深入展開了。

SpringMVC核心

MVC模式思想

如果編寫過非MVC模式的後端程式碼,直接用servlet api進行業務邏輯的實現。

一定能夠深刻的體會到MVC對後端開發帶來的巨大好處。

所謂MVC,就是將後端處理元件劃分為了模型、檢視、控制器,每個元件有自己的功能場景,在程式碼上進行了分層。使得邏輯更加清晰

@ControllerAdvice

控制器增強,一般用於控制器的全域性配置。

我經常用到的一個功能就是使用@ControllerAdvice來捕獲全域性的異常

檔案上傳

所有的MVC框架都會講到檔案上傳。

因為SpringBoot中有更簡潔的方式,這裡就不講了

HttpMessageConverter

服務端推送技術:SSE

小結

寫這篇文章,主要是為了對Sping的常見知識點做一個維護,為後續SpringBoot的展開做一個基礎。

加粗樣式