Spring是一個開源的,輕量級Java開發框架; 其核心特性是能夠用於開發任何 Java 應用程序,Spring 框架的目標是使 JavaEE應用程序的開發變得更加容易,核心概念是IOC和AOP;這也是學習Spring的重點所在;java
Spring不是針對某個具體功能,具體層級的框架; 也就是說之前該有的系統分層,結構,設計模式都不須要改變,而是讓Spring加入進來,讓開發變得更簡單; 記住Spring並不想取代某個已存在的框架,反而可讓各個框架的配合使用難度下降,它就像502膠水,可快速的在系統中集成其餘優秀的框架python
Spring也因其特性而得名,寓意爲JavaEE開發的春天來了spring
咱們常常會看到Spring替代EJB,或Spring與EJB對比等等相關文章,那麼二者之間到底有什麼關係呢?express
以前的課程中咱們知道,EJB是JavaEE規範中的一個,主要用於開發分佈式應用程序編程
從概念上來看:設計模式
因此這個問題實際上是在問Spring(框架)和JavaEE(規範)的對比,而由於二者不是同一種概念,因此沒法直接對比,那到底在對比啥? 不能在賣關子了;服務器
問題應該是:使用Spring開發和徹底按照JavaEE規範開發應用程序的區別app
這個問題應該由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容器是幫助咱們更好的解耦
控制反轉(Inversion of Control,縮寫爲IoC),是面向對象編程中的一種設計原則,能夠用來減低計算機代碼之間的耦合度。
將本來由程序實現的一部分邏輯反過來交給系統來完成就稱之爲控制反轉
其中最多見的方式叫作依賴注入(Dependency Injection,簡稱DI)經過控制反轉,能夠說,依賴被注入到對象中。
依賴注入是實現控制反轉的一種手段;
舉個例子:本身搭配組裝機,須要考慮各類部件的兼容性,和本身的性能的要求,如CPU,內存,顯卡等等;但有了專門的組裝機服務器商(IOC容器),你只要告訴他你的基本需求,好比,要一臺吃雞電腦,剩下的就交給服務商去作了;
大多數應用程序,都是有不少不一樣對象彼此合做來完成業務邏輯,這致使在獲取一個合做對象時,必須顯示的去new一個對象,這將就致使代碼高度耦合而且難以維護和調試。像下面這樣
public class Controller { @Test public void doGet() throws Exception { //這裏須要依賴Service層 UserService service = new UserService("參數1","參數2"); }
當須要更換其餘業務邏輯實現類時就不得不修改源代碼,而且若Service的實例化須要參數時,Controller層就不得不爲其提供必要的參數,這反映了Controller與Service的耦合度是較高的
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中獲取
叫作開放封閉原則,是應用程序開發中應該遵循的一個原則
open:對擴展開放
close:對修改源代碼封閉
其目的是要在不修改源代碼的狀況下對已有功能進行擴展
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的基礎功能
容器能夠理解爲存放對象的地方,固然不只僅是存儲,還有對象的管理,包括-建立-銷燬-裝配; 這樣本來程序要作的事情交給了Spring,因此這屬於IOC,稱之爲IOC容器;
Spring有兩個接口ApplicationContext是BeanFactory的子接口。它們均可以做爲Spring的容器;
BeanFactory做爲頂級接口主要面向於Spring框架自己,僅提供了基礎基本的容器功能如DI
ApplicationContext,是BeanFactory的子接口,意味着功能比BeanFactory更多,諸如國際化,註解配置,XML配置等等
BeanFactory採起的懶加載的方式,在獲取對象時纔會實例化
ApplicationContext會在工廠初始化時當即實例化對象
ApplicationContext的兩個實現類區別:
ClassPath表示從類路徑中獲取配置文件
FileSystem表示從文件系統獲取配置文件