Spring學習筆記 ——入門

Spring是什麼

首先Spring是一個輕量級控制反轉(IoC)和麪向切面(AOP)的容器框架

Spring框架是由於軟件開發的複雜性而創建的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限於服務器端的開發。從簡單性、可測試性和鬆耦合性角度而言,絕大部分Java應用都可以從Spring中受益。

也就是說,我們學習Spring是學習其理念思想也就是IoC和AOP。其適用範圍很廣,以至於任何應用都能從中受益。

Spring的優勢

  • 低侵入 / 低耦合 (降低組件之間的耦合度,實現軟件各層之間的解耦)
  • 聲明式事務管理(基於切面和慣例)
  • 方便集成其他框架(如MyBatis、Hibernate)
  • 降低 Java 開發難度
  • Spring 框架中包括了 J2EE 三層的每一層的解決方案(一站式)

Spring框架結構

Spring

一些概念

  • pojo即 Plain Old Java Objects,簡單老式 Java 對象
  • JavaBean即符合 JavaBean 規範的 Java 類。JavaBean 是一種JAVA語言寫成的可重用組件。爲寫成JavaBean,類必須是具體的和公共的,並且具有無參數的構造器。JavaBean 通過提供符合一致性設計模式的公共方法將內部域暴露成員屬性,set和get方法獲取。衆所周知,屬性名稱符合這種模式,其他Java 類可以通過自省機制(反射機制)發現和操作這些JavaBean 的屬性。

IoC

IoC:Inverse of Control(控制反轉)

  • 讀作“反轉控制”,更好理解,不是什麼技術,而是一種設計思想,就是將原本在程序中手動創建對象的控制權,交由Spring框架來管理。
  • 正控:若要使用某個對象,需要自己去負責對象的創建
  • 反控:若要使用某個對象,只需要從 Spring 容器中獲取需要使用的對象,不關心對象的創建過程,也就是把創建對象的控制權反轉給了Spring框架
  • 好萊塢法則:Don’t call me ,I’ll call you

一個常見的例子
傳統方法:
傳統構建對象方式
對於傳統模式,我們有這樣代碼實現

Juice juice = new Juice("橙子","多糖","超大杯");

工廠模式:
工廠模式
同樣的,我們有如下的代碼實現:

Shop shop = new Shop("橙子","多糖","超大杯");
Juice juice = Shop.makeJuice();

事實上對於這樣簡單的類,我們不需要引入工廠模式來增加複雜度,但是對於更加複雜的類(假如橙子,糖都是一個比較複雜的類),我們使用工廠的話會減少代碼的管理成本。

先記住這個例子,我們編寫一個簡單的Spring程序。

首先編寫一個pojo(傳統對象)

package pojo;

public class Source {  
    private String fruit;   // 類型
    private String sugar;   // 糖分描述
    private String size;    // 大小杯    
    /* setter and getter */
}

編寫配置文件裝配bean

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean name="source" class="pojo.Source">
 	<property name="fruit" value="橙子"/> 
  	<property name="sugar" value="多糖"/>
  	<property name="size" value="超大杯"/>
 </bean>
</beans>

接着來試一下Spring

ApplicationContext context = new ClassPathXmlApplicationContext(
        new String[]{"applicationContext.xml"}
);

Source source = (Source) context.getBean("source");
System.out.println(source.getFruit());
System.out.println(source.getSugar());
System.out.println(source.getSize());

輸出如下:
輸出
(我們的工程文件結構如下)
在這裏插入圖片描述
(如何創建Spring工程?)
我們使用IDEA
在這裏插入圖片描述
在這裏插入圖片描述
這樣就獲得了一個包含Spring環境的工程。

AOP

如果說 IoC 是 Spring 的核心,那麼面向切面編程就是 Spring 最爲重要的功能之一了,在數據庫事務中切面編程被廣泛使用

AOP 即 Aspect Oriented Program 面向切面編程
首先,在面向切面編程的思想裏面,把功能分爲核心業務功能,和周邊功能。

  • 所謂的核心業務,比如登陸,增加數據,刪除數據都叫核心業務
  • 所謂的周邊功能,比如性能統計,日誌,事務管理等等
    周邊功能在 Spring 的面向切面編程AOP思想裏,即被定義爲切面

在面向切面編程AOP的思想裏面,核心業務功能和切面功能分別獨立進行開發,然後把切面功能和核心業務功能 “編織” 在一起,這就叫AOP

AOP 當中的概念:

  • 切入點(Pointcut) 在哪些類,哪些方法上切入(where)
  • 通知(Advice) 在方法執行的什麼實際(when:方法前/方法後/方法前後)做什麼(what:增強的功能)
  • 切面(Aspect) 切面 = 切入點 + 通知,通俗點就是:在什麼時機,什麼地方,做什麼增強!
  • 織入(Weaving) 把切面加入到對象,並創建出代理對象的過程。(由 Spring 來完成)

AOP 編程

我們還是採用配置文件的方式來進行一個演示

首先我們編寫核心功能:

package service;

public class ProductService {
    public void doSomeService(){
        System.out.println("doSomeService");
    }
}

還有周邊功能

package aspect;
//這裏的依賴包需要額外安裝,建議看這個教程:https://blog.csdn.net/shuduti/article/details/53069241
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggerAspect {
    
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("start log:" + joinPoint.getSignature().getName());
        Object object = joinPoint.proceed();
        System.out.println("end log:" + joinPoint.getSignature().getName());
        return object;
    }
}

按照IoC的方式進行配置文檔編輯

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean name="productService" class="service.ProductService" />
    <bean id="loggerAspect" class="aspect.LoggerAspect"/>
</beans>

編寫測試方法

@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext(
            new String[]{"applicationContext.xml"}
    );
    ProductService productService = (ProductService) context.getBean("productService");
    productService.doSomeService();
}

運行
在這裏插入圖片描述
接下來,就是本節重點

我們使用AOP來切入

我們希望以doSomeService()爲切入點,在其執行前後增強日誌功能

這樣配置

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean name="productService" class="service.ProductService" />
    <bean id="loggerAspect" class="aspect.LoggerAspect"/>

    <!-- 配置AOP -->
    <aop:config>
        <!-- where:在哪些地方(包.類.方法)做增加 -->
        <aop:pointcut id="loggerCutpoint"
                      expression="execution(* service.ProductService.*(..)) "/>

        <!-- what:做什麼增強 -->
        <aop:aspect id="logAspect" ref="loggerAspect">
            <!-- when:在什麼時機(方法前/後/前後) -->
            <aop:around pointcut-ref="loggerCutpoint" method="log"/>
        </aop:aspect>
    </aop:config>
</beans>

運行:
在這裏插入圖片描述
我們獲得了日誌功能,但是沒有修改業務代碼

發佈了14 篇原創文章 · 獲贊 0 · 訪問量 896
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章