摘要:簡單來說,是一個輕量級的控制反轉和面向切面的容器框架。變成的支持提供面向切面編程,可以方便的實現對程序進行權限攔截,運行監控等功能。用于反射創建對象,默認情況下調用無參構造函數。指定對象的作用范圍。
1.Spring介紹 1.1 Spring概述
Spring是一個開源框架,Spring是于2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來。它是為了解決企業應用開發的復雜性而創建的。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限于服務器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。簡單來說,Spring是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器框架。
1.2 Spring好處
方便解耦,簡化開發
Spring就是一個大工廠,專門負責生成Bean,可以將所有對象創建和依賴關系維護由Spring管理。通過Spring提供的IoC容器,可以將對象間的依賴關系交由Spring進行控制,避免硬編碼所造成的過度程序耦合。用戶也不必再為單例模式類、屬性文件解析等這些很底層的需求編寫代碼,可以更專注于上層的應用。
AOP變成的支持
Spring提供面向切面編程,可以方便的實現對程序進行權限攔截,運行監控等功能。通過Spring的AOP功能,方便進行面向切面的編程,許多不容易用傳統OOP實現的功能可以通過AOP輕松應付。
聲明式事務的支持
只需要通過配置就可以完成對事務的管理,而無需手動編程
方便程序的測試
Spring對Junit4支持,可以通過注解方便的測試Spring程序
方便集成各種優秀框架
Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架的支持,如Struts、Hibernate、Mybatis、Quartz等
降低JavaEE API的使用難度
對JavaEE開發中一些難用的API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低
Java源碼是經典學習范例
Spring的源代碼設計精妙、結構清晰、匠心獨用,處處體現著大師對Java設計模式靈活運用以及對Java技術的高深造詣。它的源代碼無意是Java技術的最佳實踐的范例。
1.3 Spring結構體系Spring框架是一個分層架構,它包含一系列的功能要素并被分為大約20個模塊。這些模塊分為Core Container、DataAccess/Integration、Web、AOP、Instrumentation和測試部分。如下圖所示:
1.4 在項目中的架構web層:Struts,SpringMVC
dao層:Hibernate,Mybatis
1.5 程序的耦合和解耦
程序的耦合
我們開發種,會寫很多的類,而有些類之間不可避免地產生依賴關系,這種依賴關系稱為耦合。有些依賴是必須的,有些依賴關系可以通過優化代碼來解除。比如:
/** * 客戶的業務層實現類 */ public class CustomerServiceImpl implements ICustomerService { private ICustomerDao customerDao = new CustomerDaoImpl(); }
上面的代碼表示:業務調用持久層,并且此時業務再依賴持久層的接口和實現類。如果此時沒有持久層實現類,編譯將不能通過。這種依賴關系就是我們可以通過優化代碼解決的。
再比如:下面的代碼種,我們的類依賴MySQL的具體驅動類,如果這獅虎更換了數據庫品牌,我們需要改源碼來修修改數據庫驅動,這顯然不是我們想要的。
public class JdbcDemo1 { /** * JDBC操作數據庫的基本入門中存在什么問題? * 導致驅動注冊兩次是個問題,但不是嚴重的。 * 嚴重的問題:是當前類和mysql的驅動類有很強的依賴關系。 * 當我們沒有驅動類的時候,連編譯都不讓。 * 那這種依賴關系,就叫做程序的耦合 * * 我們在開發中,理想的狀態應該是: * 我們應該盡力達到的:編譯時不依賴,運行時才依賴。 * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { //1.注冊驅動 //DriverManager.registerDriver(new com.mysql.jdbc.Driver()); Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 //3.獲取預處理sql語句對象 //4.獲取結果集 //5.遍歷結果集 }
解決程序耦合的思路
在JDBC種是通過反射來注冊驅動的,代碼如下:
Clas.forName("com.mysql.jdbc.Driver");
這時的好處是,我們類中不再依賴具體的驅動類,此時就算刪除MySQL的驅動jar包,依然可以編譯。但是沒有驅動類,所以不能運行。
不過,此處也有一個問題,就是我們反射類對象的全限定類名字符串是在Java類中寫死的,一旦要改還是徐婭修改源碼。為了解決這個問題,使用配置文件配置。
工廠模式解耦
在實際開發過程總我們把所有的dao和service和action對象使用配置文件配置起來,當啟動服務器應用加載的時候,通過讀取配置文件,把這些對象創建出來并存起來。在接下來使用的時候,直接拿就好了。
控制反轉---Inversion Of Control
上面解耦的思路有兩個問題
創建的對象存儲在哪里?由于我們是很多對象,肯定要找個集合來存儲,這時候有Map和List供選擇。到底是選擇Map還是List就看我們有沒有查找的需求。有查找的需求就選Map。所以我們的答案是:在應用加載時,創建一個Map,用于存放action,service和dao對象。
還是沒解釋什么是工廠?工廠就是負責給我們從容器中獲取指定對象的類。這時候獲取對象的方式發生了改變。以前,我們在獲取對象的時候,都是采用new的方式,是主動的。
現在,我么獲取對象的時候,同時跟工廠要,有工廠為我們查找或者創建對象。是被動的。這種被動接收的方式獲取對象的思想就是控制反轉,他是Spring框架的核心之一。其作用只有一個:降低計算機程序的耦合。
2. Spring快速入門使用spring的IOC解決程序耦合
2.1 編寫流程下載Spring開發包
導入Spring的jar包
配置Spring的核心xml文件
在程序中讀取Spring的配置文件來獲取Bean【Bean其實就是一個new好的對象】
2.2 下載地址這里下載4.2.4版本
地址:http://repo.spring.io/release...
官網:spring.io 官網改版后,下載鏈接需要在對應的GitHub上找
2.3 Spring的核心jar包spring-core-4.2.4.RELEASE.jar包含Spring框架基本的核心工具類,Spring其他組件都要使用到這個包里得嘞,是其他組件的基本核心。
spring-beans-4.2.4.RELEASE.jar所有應用都要用到的,它包含訪問配置文件、創建和管理bean
以及進行Inversion of Control(IoC) / Dependency Injection(DI)操作相關的所有類。
spring-context-4.2.4.RELEASE.jarSpring提供在基礎IoC功能上的擴展服務,此外還提供許多企業級服務的支持,
如郵件服務、任務調度、JNDI定位、EJB集成、遠程訪問、緩存以及各種視圖層框架的封裝等。
spring-expression-4.2.4.RELEASE.jarSpring表達式語言。
com.springsource.org.apache.commons.logging-1.1.1.jar第三方的主要用于處理日志。
2.4 Spring入門案例
準備項目需要得jar包
spring-framework-4.2.4.RELEASE-dist.zip 【Spring的核心包】
spring-framework-4.2.4.RELEASE-dependencies.zip 【Spring的依賴包】
創建Project,導入Spring的jar包
在src路徑下創建applicationContext.xml文件
導入約束
把資源交給Spring管理,在xml文件中配置User
測試
package com.itzhouq.domain; public class User { public void run() { System.out.println("run"); } }
package com.itzhouq.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.itzhouq.domain.User; public class UserTeset { @Test public void test() {//自己new的對象 User user = new User(); user.run(); } @Test public void test2() {//spring的ioc創建對象 //加載配置文件 src/classes類路徑 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //找Spring要對象 User user = (User) context.getBean("user"); user.run(); } }3. Spring基于XML的IOC細節 3.1 IOC中bean標簽和管理對象細節 3.1.1 配置文件bean標簽
作用
用于配置對象讓Spring來創建的。默認情況下它調用的是類中的無參構造函數。如果沒有無參構造函數則不能創建成功。
屬性
id:給對象在容器中提供一個唯一標識,用于獲取對象
class:指定類的全限定名。用于反射創建對象,默認情況下調用無參構造函數。
scope:指定對象的作用范圍。
init-method:指定類中的初始化方法名稱。
destroy-method:指定類中銷毀方法名稱。
import:導入外部配置文件,resource----外部配置文件的地址。
3.1.2 scope屬性:范圍(重點)singleton: 單實例 默認值
如果是單實例,配置文件文件只要一加載 就會創建對象 放在spring容器 (map
當所有人過來問spring容器要的時候(getBean),所用人用的都是同一個對象
prototype: 多實例
如果是多實例,配置文件加載,不創建對象
當每個人過來getbean的時候,getbean一次創建一次 放在容器中
什么時候用默認值singleton(單實例)? 什么時候用prototype(多實例)?
action: prototype
service/dao: singleton
request:web項目中Spring創建一個Bean對象,將對象存入到request域中
session:web項目中Spring創建一個Bean對象,將對象存入到session域中。
globalSession:web項目中,應用在Portlet環境,如果沒有Portlet環境那么globalSession相當于session。
3.1.3 bean的作用范圍和生命周期
單例對象:scope="singleton"
一個應用只有一個對象的實例。它的作用范圍就是整個引用。
生命周期:
對象出生:當應用加載,創建容器時,對象就被創建了。
對象活著:只要容器在,對象一直活著。
對象死亡:當應用卸載,銷毀容器時,對象就被銷毀了。
多例對象:scope="prototype"
每次訪問對象時,都會重新創建對象實例。
生命周期:
對象出生:當使用對象時,創建新的對象實例。
對象活著:只要對象在使用中,就一直活著。
對象死亡:當對象長時間不用時,被java的垃圾回收器回收了。
3.1.4 示例化Bean的三種方式
無參構造方式(最常用)
@Test//測試bean的三種創建方式------無參構造方式 public void test3() { //加載配置文件 src/classes類路徑 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //找Spring要對象 User user = (User) context.getBean("user"); user.run(); }
靜態工廠方式(了解)
條件:需要有一個工廠類,在這個工廠類中還需要一個靜態方法
package com.itzhouq.utils; import com.itzhouq.domain.User; public class BeanFactory { public static User createUser() { return new User(); } }
測試
@Test//測試bean的三種創建方式------靜態工廠方式 public void test4() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user1 = (User) context.getBean("user"); System.out.println(user1);//com.itzhouq.domain.User@5f3a4b84 User user2 = (User) context.getBean("user"); System.out.println(user2);//com.itzhouq.domain.User@5f3a4b84 }
實例工廠方式(了解)
條件:需要一個工廠類在這個工廠類中需要一個普通方法
package com.itzhouq.utils; import com.itzhouq.domain.User; public class BeanFactory { // public static User createUser() { // return new User(); // } //普通方法----實例工廠 public User createUser() { return new User(); } }
配置文件
測試
@Test//測試bean的三種創建方式------實例工廠方式 public void test5() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user1 = (User) context.getBean("user"); System.out.println(user1);//com.itzhouq.domain.User@5f3a4b84 User user2 = (User) context.getBean("user"); System.out.println(user2);//com.itzhouq.domain.User@5f3a4b84 }3.2 加載Spring容器的三種方式
類路徑獲得配置文件
文件系統路徑獲得配置文件
使用BeanFactory(了解)
public class Lession01 { @Test public void test01(){ //Spring容器加載有3種方式 //第一種:ClassPathXmlApplicationContext ClassPath類路徑加載:指的就是classes路徑 //最常用,Spring的配置文件以后就放在src路徑下 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //第二種方式:文件系統路徑獲得配置文件【絕對路徑】 ApplicationContext context = new FileSystemXmlApplicationContext("E:workspacesIdeaProjectSpring-day02-gyfsrceans.xml"); IUserService user = (IUserService) context.getBean("userService"); user.add(); //第三種方式: String path = "E:workspacesIdeaProjectSpring-day02-gyfsrceans.xml"; BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path)); IUserService user1 = (IUserService) factory.getBean("userService"); user1.add(); } }
Spring內部創建對象的原理
1. 解析xml文件,獲得類名,id,屬性 2. 通過反射,用類型創建對象 3. 給創建的對象賦值3.3 BeanFactory和ApplicationContext對比
BeanFactory采用延遲加載,第一次getBean時才會初始化Bean
ApplicationContext是對BeanFactory擴展,提供了更多功能
國際化處理
事件傳遞
Bean自動裝配
各種不同應用的Context實現
3. 4 Spring的依賴注入DIDI屬性的依賴注入,是Spring框架核心IoC的具體實現方式。Spring在通過Ioc創建對象的時候,如果這個對象還有屬性,就一并賦值進去,而不用我們自己去獲取。
入門舉例:
創建一個接口Car
package com.itzhouq.service; public interface Car { public void run(); }
創建實現類CarImpl
package com.itzhouq.serviceImpl; import com.itzhouq.service.Car; public class CarImpl implements Car { private String name; public void setName(String name) { this.name = name; } @Override public void run() { System.out.println(name+"車跑起來了....."); } }
測試
package com.itzhouq.test; import org.junit.Test; import com.itzhouq.serviceImpl.CarImpl; public class CarTest { @Test//自己new對象 自己屬性賦值的方式 public void test() { CarImpl car = new CarImpl(); car.setName("qq"); car.run();//qq車跑起來了..... } }
入門舉例2:依賴注入的方式
配置文件:
測試
@Test //Spring的IOC public void test2() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Car car = (Car)context.getBean("car"); //把這個對象的屬性也在創建的時候給順便賦值了-----DI car.run();//蘭博基尼車跑起來了..... }
依賴注入的方式
構造函數注入(了解)
set方法注入(掌握)
使用p名稱空間注入數據(本質還是調用set方法)(了解)
注入集合屬性
3.4.1 構造器注入方式條件:需要有有參構造方法
給CarImpl設置有參構造
package com.itzhouq.serviceImpl; import com.itzhouq.service.Car; public class CarImpl implements Car { private String name; private double price; public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getName() { return name; } public CarImpl() {} //有參的構造方法----DI的構造器注入方式 public CarImpl(String name, double price) { super(); this.name = name; this.price = price; } @Override public void run() { System.out.println("價值"+price+"的"+name+"車跑起來了....."); } }
配置文件
測試
@Test //Spring的DI注入方式----構造器的注入方式(了解) public void test3() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Car car = (Car)context.getBean("car"); car.run();//價值1000000.0的BMW車跑起來了..... }3.4.2 set方式注入
寫一個Person接口
package com.itzhouq.service; public interface Person { }
PersonImpl實現接口Person,設置set方法
package com.itzhouq.serviceImpl; import com.itzhouq.service.Car; import com.itzhouq.service.Person; public class PersonImpl implements Person { private String name; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "PersonImpl [name=" + name + ", car=" + car + "]"; } }
配置文件
測試
@Test //Spring的DI注入方式----set的注入方式(了解) public void test4() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Person person = (Person) context.getBean("person"); System.out.println(person); //PersonImpl [name=jack, car=CarImpl [name=BMW, price=1000000.0]] }3.4.3 使用p名稱空間注入數據(知道就OK)
此種方式是通過在xml中導入p名稱空間,使用p:propertyName來注入數據,它的本質仍然是調用類中的set方法實現注入功能。
配置文件
3.4.4 注入集合屬性
顧名思義,就是給類中的集合成員傳值,它用的也是set方法注入的方式,只不過變量的數據類型都是集合。我們這里介紹注入數組,List,Set,Map,Properties。
創建一個類CollBean,設置set方法
package com.itzhouq.domain; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; public class CollBean { private String[] ss; private List ll; private Map mm; private Properties properties; public String[] getSs() { return ss; } public void setSs(String[] ss) { this.ss = ss; } public List getLl() { return ll; } public void setLl(List ll) { this.ll = ll; } public Map getMm() { return mm; } public void setMm(Map mm) { this.mm = mm; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } @Override public String toString() { return "CollBean [ss=" + Arrays.toString(ss) + ", ll=" + ll + ", mm=" + mm + ", properties=" + properties + "]"; } }
配置文件
aaa bbb ccc root 1234
測試
package com.itzhouq.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.itzhouq.domain.CollBean; public class CollBeanTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); CollBean cb = (CollBean) context.getBean("collBean"); System.out.println(cb); /* * CollBean [ss=[aaa, bbb, ccc], * ll=[111, 222, CarImpl [name=BMW, price=1000000.0]], * mm={k1=AAA, k2=BBB, k3=CarImpl [name=BMW, price=1000000.0]}, * properties={hibernate.password=1234, hibernate.username=root}] */ } }4.使用案例
需求分析:從service層調用dao層,將數據存儲到數據庫,存儲數據的過程使用syso模擬一下就可以。
創建工程,導入需要的jar包,建包如下:
創建dao層和dao實現層
package com.itzhouq.dao; public interface UserDao { void save(); }
package com.itzhouq.daoImpl; import com.itzhouq.dao.UserDao; public class UserDaoImpl implements UserDao{ @Override public void save() { System.out.println("操作數據庫,保存用戶的數據"); } }
創建Service層和實現層
package com.itzhouq.service; public interface UserService { public void save(); }
package com.itzhouq.serviceImpl; import com.itzhouq.dao.UserDao; import com.itzhouq.daoImpl.UserDaoImpl; import com.itzhouq.service.UserService; public class UserServiceImpl implements UserService { private String name; private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void setName(String name) { this.name = name; } @Override public void save() { System.out.println(name); //調用dao userDao.save(); } }
給UserDaoImpl一個UserDao屬性
配置文件
測試
@Test //使用Spring的IOC+DI來實現對象的創建和賦值 public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("UserService"); userService.save(); //要開始訪問dao了 //操作數據庫,保存用戶的數據 }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74363.html
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:現在的分片策略是上海深圳分別建庫,每個庫都存各自交易所的兩支股票的,且按照月分表。五配置分片策略數據庫分片策略在這個實例中,數據庫的分庫就是根據上海和深圳來分的,在中是單鍵分片。 由于當當發布了最新的Sharding-Sphere,所以本文已經過時,不日將推出新的版本 項目中遇到了分庫分表的問題,找到了shrding-jdbc,于是就搞了一個springboot+sharding-jd...
摘要:項目介紹風格的一套系統,前端采用作為前端框架,后端采用作為服務框架,采用自封裝的對所有請求進行參數校驗,以保證接口安全性。 skyeye 項目介紹 win10風格的一套系統,前端采用layui作為前端框架,后端采用SpringBoot作為服務框架,采用自封裝的xml對所有請求進行參數校驗,以保證接口安全性。 項目地址:https://gitee.com/doc_wei01_a...該項...
摘要:時間年月日星期四說明本文部分內容均來自慕課網。那么里面的數據就可以分為各種各樣的索引,比如汽車索引圖書索引家具索引等等。圖書索引又可以細分為各種類型,比如科普類小說類技術類等等。具體到每一本書籍,就是文檔,就是整個圖書里面最小的存儲單位。 時間:2017年09月14日星期四說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學源碼:無學習源碼:https...
閱讀 1741·2023-04-25 23:43
閱讀 912·2021-11-24 09:39
閱讀 717·2021-11-22 15:25
閱讀 1718·2021-11-22 12:08
閱讀 1089·2021-11-18 10:07
閱讀 2077·2021-09-23 11:22
閱讀 3343·2021-09-22 15:23
閱讀 2486·2021-09-13 10:32