Spring入門(一) 環境搭建、IOC/AOP快速上手

環境搭建

構建 Spring 開發環境需要用到 5 個 jar 包,包括 4 個 Spring 基礎包以及一個第三方日誌包。

Spring FrameWork 下載教程:Spring Framework 5.0.0下載

日誌 jar 包下載地址: commons-logging

將下載的 Spring FrameWork 壓縮包解壓後,進入 libs 目錄,可以看到如下文件:

Spring 框架每一個模塊由 3 個 jar 包組成,例如 aop 模塊由以下三個 jar 包組成:

  • spring-aop-5.2.0.RELEASE.jar:二進制文件(.class 文件)
  • spring-aop-5.2.0.RELEASE-sources.jar:源碼
  • spring-aop-5.2.0.RELEASE-javadoc.jar:在線幫助文檔

Spring 框架基礎包有以下 4 個:

  • spring-beans-5.2.0.RELEASE.jar:IOC 的基礎實現,包含訪問配置文件、創建和管理 bean 等
  • spring-context-5.2.0.RELEASE.jar:Spring 提供的在基礎 IoC 功能上的擴展服務
  • spring-core-5.2.0.RELEASE.jar:Spring 框架的核心,其他模塊都要依賴它
  • spring-expression-5.2.0.RELEASE.jar:Spring 表達式語言

新建 Java 工程,創建 lib 目錄,將上面提到的 5 個 jar 包拷貝到 lib 目錄下,然後將它們添加到類庫。

在 src 目錄下添加配置文件 applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

如果在 Eclipse 中安裝 Spring 插件 spring tool suite,創建配置文件時,插件就能爲我們自動生成上面的內容。當然,你也可以直接使用 STS(Spring 官網提供的集成 Spring 插件的 Eclipse)。

以上步驟完成後,項目結構如下所示:

 

IOC 快速上手

現在我們有一個 Student 類,類信息如下:

public class Student {
	private String no;
	private String name;
	private int age;
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [no=" + no + ", name=" + name + ", age=" + age + "]";
	}
}

按照以往的方式,如果我們要使用 Student 對象,需要經過創建對象、爲對象的屬性賦值兩個步驟:

private static void createStudentByCommon() {
	Student student = new Student();
	student.setNo("s-001");
	student.setName("zhangsan");
	student.setAge(21);
	System.out.println(student);
}

使用 IOC 的方式獲取 Student 對象也需要兩個步驟。

一、在 applicationContext.xml 中配置 bean

配置 bean 主要需要三個參數:

  1. id:bean 唯一標識符,保證 bean 在 IOC 容器唯一
  2. class:bean 類型,和 Java 類對應(需要使用全類名
  3. property:bean 屬性,和 Java 類的屬性對應
<bean id="stu_2" class="org.hu.entity.Student">
	<property name="no" value="s-002"></property>
	<property name="name" value="lisi"></property>
	<property name="age" value="24"></property>
</bean>

二、從 IOC 容器中獲取 bean

想從 IOC 容器中拿取東西,首先要有 IOC 容器,我們需要用配置文件初始化 IOC 容器。然後根據配置文件中 bean 的 id 獲取 bean,由於 bean 都是 Object 類型,將 bean 強制轉換爲相應的類型即可:

private static void createStudentByIOC() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	Student student = (Student)context.getBean("stu_2");
	System.out.println(student);
}

兩種方式運行結果:

以上兩種獲取對象的方式都經歷了創建對象、爲對象賦值兩個步驟。不同之處在於,傳統方式的獲取對象需要我們手動完成這兩個步驟;而通過 IOC 方式的獲取對象,IOC 容器會負責完成這兩個步驟,我們只需要從 IOC 容器中獲取就可以了。

 

AOP 快速上手

想要使用 AOP 功能,需要在項目中再引入 3 個 jar 包:Spring Framework 提供的 aop 包以及兩個第三方包:

將上面 3 個包添加到類庫後,在 applicationContext.xml 配置文件中勾選 aop 支持:

現在我們有一個學生服務的接口,裏面聲明有添加學生的方法:

public interface IStudentService {
	void addStudent(Student stu);
}

實現該接口:

public class StudentServiceImpl implements IStudentService {
	@Override
	public void addStudent(Student stu) {
		System.out.println("add student:" + stu.getName() + "," + stu.getAge());
	}
}

我想各位在項目開發過程中,應該都寫過類似下面的代碼:

private static void LogBeforeByCommon() {
	IStudentService iStudentService = new StudentServiceImpl();
	Student stu = new Student();
	stu.setName("wangwu");
	stu.setAge(25);
	System.out.println("start to add student...");
	iStudentService.addStudent(stu);
}

打印 log 可以幫助我們瞭解相關代碼是否執行,但是等到項目通過測試後,我們還需要把自己親手寫下的打印 log 代碼註釋掉或刪除(說到這裏,我就想起了曾經被分配到的一個任務:刪除項目中 log 相關的代碼,刪的我想死的心都有了)。像打印 log 這樣的代碼,通常會散亂的分佈在項目各個角落,它們和業務邏輯沒有什麼關聯,但是又和業務代碼牢牢的粘合在一起。爲了讓這類代碼和業務代碼解耦,AOP 出現了。

下面我們就實際體驗一下 AOP。

首先,既然 AOP 的目的是解耦業務代碼和非業務代碼(打印 log),那麼我們就要把非業務代碼抽離出來。其次,爲了讓 Spring 區分哪些是非業務代碼,就要遵循一定的規範。

結合以上兩點,創建 LogBefore 類並實現 aop 包中提供的 MethodBeforeAdvice 接口,重寫 before() 方法:

public class LogBefore implements MethodBeforeAdvice {
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		System.out.println("start to add student...");
	}
}

現在業務代碼和非業務代碼都已編寫完成,如何將二者聯繫起來呢?答案是配置文件。

在 applicationContext.xml 中添加 aop 相關配置:

<bean id="stuSerImp" class="org.hu.service.StudentServiceImpl"/>
<bean id="logBef" class="org.hu.aop.LogBefore" />
<aop:config>
    <aop:pointcut id="addstu"
       expression="execution(public void org.hu.service.StudentServiceImpl.addStudent(org.hu.entity.Student))" />
    <aop:advisor advice-ref="logBef" pointcut-ref="addstu"/>
</aop:config>

這裏我主要解釋一下兩個標籤的作用:

  1. aop:pointcut:切點,指定業務代碼(某個類裏的某個方法)。
  2. aop:advisor:通知,指定非業務代碼(以 bean 形式配置)以及需要關聯的業務代碼。

編寫測試代碼:

private static void LogBeforeByAOP() {
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
	IStudentService iStudentService = (IStudentService)context.getBean("stuSerImp");
	iStudentService.addStudent((Student)context.getBean("stu_2"));
}

兩種方式運行結果:

 

項目代碼:https://github.com/BWHN/spring

 

參考:

Spring的各個jar包的作用介紹

Spring AOP 簡介以及簡單用法

自己實現Spring AOP(一)環境搭建及知識準備

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章