什么是Spring
Spring是一個開源的,輕量級Java開發框架; 其核心特性是可以用於開發任何 Java 應用程序,Spring 框架的目標是使 JavaEE應用程序的開發變得更加容易,核心概念是IOC和AOP;這也是學習Spring的重點所在;
Spring不是針對某個具體功能,具體層級的框架; 也就是說以前該有的系統分層,結構,設計模式都不需要改變,而是讓Spring加入進來,讓開發變得更簡單; 記住Spring並不想取代某個已存在的框架,反而可以讓各個框架的配合使用難度降低,它就像502膠水,可快速的在系統中集成其他優秀的框架
Spring也因其特性而得名,寓意為JavaEE開發的春天來了
為什么需要Spring
我們經常會看到Spring替代EJB,或Spring與EJB對比等等相關文章,那么兩者之間到底有什么關系呢?
之前的課程中我們知道,EJB是JavaEE規范中的一個,主要用於開發分布式應用程序
從概念上來看:
- Spring是一個框了架,框架是幫你實現了一部分功能的半成品
- 而EJB是一個規范,用來規范(指導)開發者,如何去實現JavaEE程序
所以這個問題其實是在問Spring(框架)和JavaEE(規范)的對比,而因為兩者不是同一種概念,所以無法直接對比,那到底在對比啥? 不能在賣關子了;
問題應該是:使用Spring開發和完全按照JavaEE規范開發應用程序的區別
這個問題應該由Spring的作者Rod Johnson來回答:
#Rod Johnson在2002年編寫的《Expert One-to-One J2EE Design and Development》一書,Rod 在本書中對J2EE正統框架臃腫、低效、脫離現實的種種學院派做法提出了質疑,並以此書為指導思想,編寫了interface21框架,也就是后來的Spring。
的確推出Spring推出就是民間開發者對官方規范的中不足的地方提出的質疑以及做出的強力回應,在早期階段,開發者們經歷了擁抱到拋棄,從最早的JavaEE這一官方協議推出后,開發者們非常擁戴,畢竟是官方嘛,后來慢慢發現這堆復雜,晦澀,學習成本極高的規范是多么的臃腫不堪,就像你為了打一只小鳥而搬出了戰斗機;就在這時候Spring框架應運而生,因其輕量級,使用簡單很快受到了大家的喜愛;
好在官方也意識到了問題,於是在EJB3.0做出了大量的改進,並借鑒了Spring中一些非常優秀的特性,但如日中天的Spring好像並沒有受到太大的影響,大家一如既往的喜愛Spring;
EJB容器IOC容器
另一方面因為Spring具備ICO容器,可以幫助我們管理Bean,而EJB的需要放在EJB容器中才能使用其提供的功能; EJB主要用於提供分布式能力,而IOC容器是幫助我們更好的解耦
Spring的優點
- Spring 對JavaEE中的一些API(JDBC、JavaMail、遠程調用等),提供了封裝,使這些API使用難度降低;
- 一站式框架,可簡單快速的集成其他框架;
- IOC,利用依賴注入,極大的降低各組件間的耦合,提高整體擴展性;
- AOP(面向切面)編程的支持,可以方便的對程序進行權限攔截,運行監控等;
- 聲明式事務支持,通過配置就可以完成對事務的管理,無序進行手動編程;
- 容器化,Spring包含並管理應用對象的配置和生命周期,你可以配置每個bean如何被創建以及bean是一個單獨的實例或者每次需要時都生成一個新的實例,以及它們是如何相互關聯的。
IOC,DI
概念
控制反轉(Inversion of Control,縮寫為IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。
將原本由程序實現的一部分邏輯反過來交給系統來完成就稱之為控制反轉
其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI)通過控制反轉,可以說,依賴被注入到對象中。
依賴注入是實現控制反轉的一種手段;
為何需要IOC
舉個例子:自己搭配組裝機,需要考慮各種部件的兼容性,和自己的性能的要求,如CPU,內存,顯卡等等;但有了專門的組裝機服務器商(IOC容器),你只要告訴他你的基本需求,比如,要一台吃雞電腦,剩下的就交給服務商去做了;
大多數應用程序,都是有很多不同對象彼此合作來完成業務邏輯,這導致在獲取一個合作對象時,必須顯示的去new一個對象,這將就導致代碼高度耦合並且難以維護和調試。像下面這樣
public class Controller {
@Test
public void doGet() throws Exception {
//這里需要依賴Service層
UserService service = new UserService("參數1","參數2");
}
當需要更換其他業務邏輯實現類時就不得不修改源代碼,並且若Service的實例化需要參數時,Controller層就不得不為其提供必要的參數,這反映了Controller與Service的耦合度是較高的
Spring體系結構

core,提供了框架基礎組成部分,包括IoC和DI;
beans,提供了BeanFactory,是工廠模式的實現,提供普通對象和單例對象的獲取
context,建立在core和bean的基礎上,可將其他庫集成到Spring中
SpEL(spring-expression Language)提供了表達式語言支持,其對JSP中的EL進行了擴展
AOP,提供了面向切面編程實現
Aspects 模塊提供了與 AspectJ 的集成,是一個功能強大且成熟的AOP框架
Instrumentation 用於代理監控JVM運行的JAVA程序,對字節碼修改以實現AOP
Messaging 模塊為 STOMP 提供了支持,主要處理來自 WebSocket 客戶端的 STOMP 信息
強調:
Spring是模塊化的,完全可以根據需要來導入所需模塊
使用入門
傳統寫法
先來看一個不使用Spring時,控制和業務邏輯層交互的案例,控制器:
public class Controller {
@Test
public void doGet() throws Exception {
//這里需要依賴Service層
//v1 直接寫
//UserService service = new UserService();
//v2 面向接口 某個實現類
//UserService service = new UserServiceImpl();
//要跟換其他實現類時 違反了OCP(開放封閉)原則
//UserService service = new UserServiceImpl2();
//v3 為避免修改源代碼擴展 加入工廠
ServiceFactory factory = new ServiceFactory();
UserService service = factory.getService();
//調用業務方法
service.userLogin("jerry","admin");
}
}
工廠:
public class ServiceFactory {
public UserService getService() throws Exception {
//此處id應配置在xml中
String id = "UserServiceImpl";
if (id.equals("UserServiceImpl")){
return new UserServiceImpl();
}else if(id.equals("UserServiceImpl2")){
return new UserServiceImpl2();
}
throw new Exception("id:"+id + "not register");
}
}
使用工廠模式可以進一步降低組件間的耦合度,但在完整的系統中有很多組件,需要很多個工廠,使程序變得復雜,臃腫;
Spring將自身設計為一個大型對象工廠,負責管理系統中設計到的所有對象,並利用DI處理對象的依賴關系,當對象A需要對象B時不再自己創建而是從Spring中獲取

補充說明:OCP
叫做開放封閉原則,是應用程序開發中應該遵循的一個原則
open:對擴展開放
close:對修改源代碼封閉
其目的是要在不修改源代碼的情況下對已有功能進行擴展
使用Spring
1.創建Maven項目
2.添加依賴
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- Maven會自動下載所有Spring核心容器和aop的依賴-->
3.創建配置文件
通常名為:applicationContext.xml當然你也可以修改放在resources下
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用bean標簽,創建Service對象,並交給容器來管理-->
<bean id="UserService1" class="com.yyh.serviceimpl.UserServiceImpl"/>
<bean id="UserService2" class="com.yyh.serviceimpl.UserServiceImpl2"/>
</beans>
名稱空間聲明可到官網查找,或是直接在jar中查找,如:

4.從Spring中獲取需要的對象
@Test
public void doGetUseSpring() throws Exception {
//創建應用上下文 指定配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//從Spring中獲取所需對象
UserService userService = (UserService)context.getBean("UserService2");
//調用業務邏輯方法
userService.userLogin("jerry","admin");
}
不難看出此時的Spring就是一個對象工廠,但這僅僅Spring的基礎功能
下一篇
