天天看點

【spring】spring知識點總結(spring boot工程)1、spring概述2、 IoC 控制反轉3、AOP 面向切面程式設計

spring

  • 1、spring概述
    • 1.1spring是什麼
    • 1.2spring優點
    • 1.3spring體系結構
  • 2、 IoC 控制反轉
    • 2.1概念
    • 2.2基于注解的DI
      • 定義 Bean 的注解
      • 屬性注入
  • 3、AOP 面向切面程式設計
    • 3.1概念
    • 3.2AOP程式設計術語
    • 3.3AspectJ 對 AOP 的實作
      • AspectJ 中常用的通知有五種類型:
      • AspectJ 的切入點表達式
      • AspectJ 的依賴
      • AspectJ 基于注解的 AOP 實作

1、spring概述

1.1spring是什麼

Spring 是于 2003 年興起的一個輕量級的 Java 開發架構,它是為了解決企業應用開發的複雜性而建立的。Spring 的核心是控制反轉(IoC)和面向切面程式設計(AOP)。Spring 是可以在 Java SE/EE 中使用的輕量級開源架構。

Spring 的主要作用就是為代碼“解耦”,降低代碼間的耦合度。就是讓對象和對象(模

塊和子產品)之間關系不是使用代碼關聯,而是通過配置來說明。即在 Spring 中說明對象(子產品)的關系。Spring 根據代碼的功能特點,使用 Ioc 降低業務對象之間耦合度。IoC 使得主業務在互相調用過程中,不用再自己維護關系了,即不用再自己建立要使用的對象了。而是由 Spring容器統一管理,自動“注入”,注入即指派。 而 AOP 使得系統級服務得到了最大複用,且不用再由程式員手工将系統級服務“混雜”到主業務邏輯中了,而是由 Spring 容器統一完成“織入”。

官網:https://spring.io/

1.2spring優點

Spring 是一個架構,是一個半成品的軟體。有 20 個子產品組成。它是一個容器管理對象,容器是裝東西的,Spring 容器不裝文本,數字。裝的是對象。Spring 是存儲對象的容器。

(1) 輕量

Spring 架構使用的 jar 都比較小,一般在 1M 以下或者幾百 kb。Spring 核心功能的所需的 jar 總共在 3M 左右。Spring 架構運作占用的資源少,運作效率高。不依賴其他 jar

(2) 針對接口程式設計,解耦合

Spring 提供了 Ioc 控制反轉,由容器管理對象,對象的依賴關系。原來在程式代碼中的對象建立方式,現在由容器完成。對象之間的依賴解耦合。

Spring 是于 2003 年興起的一個輕量級的 Java 開發架構,它是為了解決企業應用開發的複雜性而建立的。Spring 的核心是控制反轉(IoC)和面向切面程式設計(AOP)。Spring 是可以在 Java SE/EE 中使用的輕量級開源架構。

(3) AOP 程式設計的支援

通過 Spring 提供的 AOP 功能,友善進行面向切面的程式設計,許多不容易用傳統 OOP 實作的功能可以通過 AOP 輕松應付在 Spring 中,開發人員可以從繁雜的事務管理代碼中解脫出來,通過聲明式方式靈活地進行事務的管理,提高開發效率和品質。

(4) 友善內建各種優秀架構

Spring 不排斥各種優秀的開源架構,相反 Spring 可以降低各種架構的使用難度,Spring提供了對各種優秀架構(如 Struts,Hibernate、MyBatis)等的直接支援。簡化架構的使用。Spring 像插線闆一樣,其他架構是插頭,可以容易的組合到一起。需要使用哪個架構,就把這個插頭放入插線闆。不需要可以輕易的移除。

1.3spring體系結構

【spring】spring知識點總結(spring boot工程)1、spring概述2、 IoC 控制反轉3、AOP 面向切面程式設計

2、 IoC 控制反轉

2.1概念

控制反轉(IoC,Inversion of Control),是一個概念,是一種思想。指将傳統上由程式代碼直接操控的對象調用權交給容器,通過容器來實作對象的裝配和管理。控制反轉就是對對象控制權的轉移,從程式代碼本身反轉到了外部容器。通過容器實作對象的建立,屬性指派,依賴的管理。

IoC 是一個概念,是一種思想,其實作方式多種多樣。目前比較流行的實作方式是依賴注入。應用廣泛。

依賴:classA 類中含有 classB 的執行個體,在 classA 中調用 classB 的方法完成功能,即 classA對 classB 有依賴。

Ioc 的實作:

依賴注入:DI(Dependency Injection),程式代碼不做定位查詢,這些工作由容器自行完成。依賴注入 DI 是指程式運作過程中,若需要調用另一個對象協助時,無須在代碼中建立被調用者,而是依賴于外部容器,由外部容器建立後傳遞給程式。

Spring 的依賴注入對調用者與被調用者幾乎沒有任何要求,完全支援對象之間依賴關系的管理。Spring 架構使用依賴注入(DI)實作 IoC。

Spring 容器是一個超級大工廠,負責建立、管理所有的 Java 對象,這些 Java 對象被稱為 Bean。Spring 容器管理着容器中 Bean 之間的依賴關系,Spring 使用“依賴注入”的方式來管理 Bean 之間的依賴關系。使用 IoC 實作對象之間的解耦和。

2.2基于注解的DI

定義 Bean 的注解

@Component用于普通java類進行注解

@Repository 用于對 DAO 實作類進行注解

@Service 用于對 Service 實作類進行注解

@Controller 用于對 Controller 實作類進行注解

屬性注入

簡單類型屬性注入@Value

byType 自動注入@Autowired

byName 自動注入@Autowired 與@Qualifier

例如:

@Autowired
@Qualifier("mySchool")
 private School school;
           

JDK 注解@Resource 自動注入

3、AOP 面向切面程式設計

3.1概念

AOP(Aspect Orient Programming),面向切面程式設計。面向切面程式設計是從動态角度考慮程式運作過程。AOP 底層,就是采用動态代理模式實作的。采用了兩種代理:JDK 的動态代理,與 CGLIB的動态代理。

AOP 為 Aspect Oriented Programming 的縮寫,意為:面向切面程式設計,可通過運作期動态代理實作程式功能的統一維護的一種技術。AOP 是 Spring 架構中的一個重要内容。利用 AOP可以對業務邏輯的各個部分進行隔離,進而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

面向切面程式設計,就是将交叉業務邏輯封裝成切面,利用 AOP 容器的功能将切面織入到主業務邏輯中。所謂交叉業務邏輯是指,通用的、與主業務邏輯無關的代碼,如安全檢查、事務、日志、緩存等。若不使用 AOP,則會出現代碼糾纏,即交叉業務邏輯與主業務邏輯混合在一起。這樣,會使主業務邏輯變的混雜不清。

例如,轉賬,在真正轉賬業務邏輯前後,需要權限控制、日志記錄、加載事務、結束事務等交叉業務邏輯,而這些業務邏輯與主業務邏輯間并無直接關系。但,它們的代碼量所占比重能達到總代碼量的一半甚至還多。它們的存在,不僅産生了大量的“備援”代碼,還大大幹擾了主業務邏輯—轉賬。

3.2AOP程式設計術語

(1) 切面(Aspect)

切面泛指交叉業務邏輯。上例中的事務處理、日志處理就可以了解為切面。常用的切面是通知(Advice)。實際就是對主業務邏輯的一種增強。

(2) 連接配接點(JoinPoint)

連接配接點指可以被切面織入的具體方法。通常業務接口中的方法均為連接配接點。

(3) 切入點(Pointcut)

切入點指聲明的一個或多個連接配接點的集合。通過切入點指定一組方法。被标記為 final 的方法是不能作為連接配接點與切入點的。因為最終的是不能被修改的,不能被增強的。

(4) 目标對象(Target)

目 标 對 象 指 将 要 被 增 強 的 對 象 。 即 包 含 主 業 務 邏 輯 的 類 的 對 象 。 上 例 中 的StudentServiceImpl 的對象若被增強,則該類稱為目标類,該類對象稱為目标對象。當然,不被增強,也就無所謂目标不目标了。

(5) 通知(Advice)

通知表示切面的執行時間,Advice 也叫增強。上例中的 MyInvocationHandler 就可以了解為是一種通知。換個角度來說,通知定義了增強代碼切入到目标代碼的時間點,是目标方法執行之前執行,還是之後執行等。通知類型不同,切入時間不同。

切入點定義切入的位置,通知定義切入的時間。

3.3AspectJ 對 AOP 的實作

AspectJ 中常用的通知有五種類型:

(1)前置通知

(2)後置通知

(3)環繞通知

(4)異常通知

(5)最終通知

AspectJ 的切入點表達式

AspectJ 定義了專門的表達式用于指定切入點。表達式的原型是:

execution(modifiers-pattern? ret-type-pattern

declaring-type-pattern?name-pattern(param-pattern)

throws-pattern?)

modifiers-pattern] 通路權限類型

ret-type-pattern 傳回值類型

declaring-type-pattern 包名類名

name-pattern(param-pattern) 方法名(參數類型和參數個數)

throws-pattern 抛出異常類型

?表示可選的部分

AspectJ 是一個優秀面向切面的架構,它擴充了 Java 語言,提供了強大的切面實作。以上表達式共 4 個部分。

execution(通路權限 方法傳回值 方法聲明(參數) 異常類型)

切入點表達式要比對的對象就是目标方法的方法名。是以,execution 表達式中明顯就是方法的簽名。注意,表達式中黑色文字表示可省略部分,各部分間用空格分開。在其中可以使用以下符号:

【spring】spring知識點總結(spring boot工程)1、spring概述2、 IoC 控制反轉3、AOP 面向切面程式設計

AspectJ 的依賴

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
           

AspectJ 基于注解的 AOP 實作

定義業務接口與實作類

public interface SomeService {
    void doSome();
    String doOther();
    String surround();
}
@Component
public class SomeServiceImp implements SomeService {
    @Override
    public void doSome() {
        System.out.println("doSome");
    }

    @Override
    public String doOther() {
        System.out.println("doOther");
        return "hello";
    }

    @Override
    public String surround(){
        System.out.println("surround");
        return "cao";
    }
}
           

定義切面類

前置通知

@Aspect
@Component
public class MyAspect {
    /**
    前置通知
    */
    @Before("execution(public void com.guet.mybatis.service.imp.SomeServiceImp.doSome())")
    public void myBefore(JoinPoint jp){
        System.out.println(jp.getSignature());
        System.out.println("前置通知");
    }
}
           

後置通知

@Aspect
@Component
public class MyAspect2 {
    @AfterReturning( value = "execution(public String com.guet.mybatis.service.imp.SomeServiceImp.doOther())",returning = "result")
    public void myAfterReturn(JoinPoint jp,Object result){
        System.out.println("後置通知");
        System.out.println(jp.getSignature());
        System.out.println("傳回值"+(String)result);
    }
}
           

環繞通知

@Aspect
@Component
public class MyAspect3 {
    @Around("execution(public String com.guet.mybatis.service.imp.SomeServiceImp.surround())")
    public Object mySurround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object obj;
        System.out.println("前置通知");
        obj = proceedingJoinPoint.proceed();
        System.out.println("後置通知");
        String s = "diaoniam";
        return s;
    }
}
           

在目标方法執行之前之後執行。被注解為環繞增強的方法要有傳回值,Object 類型。并且方法可以包含一個 ProceedingJoinPoint 類型的參數。接口 ProceedingJoinPoint 其有一個proceed()方法,用于執行目标方法。若目标方法有傳回值,則該方法的傳回值就是目标方法的傳回值。最後,環繞增強方法将其傳回值傳回。該增強方法實際是攔截了目标方法的執行。

繼續閱讀