目錄
一、前言
1.1.Spring簡介
1.2.使用Spring的優(yōu)點
1.3.Spring組成
二、Spring之IOC詳解
2.1.IOC理論推導
2.1.1.IOC分析實現
2.1.2.IOC本質
2.2.Maven項目導入Jar包
2.3.依賴注入
2.3.1.Set注入(重點)
2.3.2.構造注入
無參構造創(chuàng)建對象
有參構造創(chuàng)建對象
2.4.自動裝配
byName(按名稱自動裝配)
byType?(按類型自動裝配)
2.5.spring與web容器的整合
一、前言
1.1.Spring簡介
Spring翻譯過來就是春天的意思,它的出現也是給廣大程序員帶來了春天??。
Spring框架最初由Rod Johnson創(chuàng)建,他于2002年寫了一本名為《Expert One-on-One J2EE Design and Development》的書,書中詳細介紹了一些與J2EE技術有關的設計模式和最佳實
踐。該書的成功激發(fā)了Rod Johnson繼續(xù)探索J2EE開發(fā)的方法,最終他開發(fā)了Spring框架。
2004年,Spring框架發(fā)布了第一個正式版本1.0,這個版本包括IoC容器、AOP、數據訪問等核心特性。
Spring官網http:// http://spring.io/Spring官方下載地址https://repo.spring.io/libs-release-local/org/springframework/spring/
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency>
1.2.使用Spring的優(yōu)點
Spring是一個開源框架,它由Rod Johnson創(chuàng)建。它是為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的。
? ?Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。
? ?然而,Spring的用途不僅限于服務器端的開發(fā)。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。
? ?目的:解決企業(yè)應用開發(fā)的復雜性
? ?功能:使用基本的JavaBean代替EJB,并提供了更多的企業(yè)應用功能
? ?范圍:任何Java應用
? ?簡單來說,Spring是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器框架。
1.3.Spring組成
Spring 框架是一個分層架構,由 7 個定義良好的模塊組成。Spring 模塊構建在核心容器之上,核心容器定義了創(chuàng)建、配置和管理 bean 的方式 .
組成 Spring 框架的每個模塊(或組件)都可以單獨存在,或者與其他一個或多個模塊聯合實現。每個模塊的功能如下:
- 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要組件是 BeanFactory,它是工廠模式的實現。BeanFactory 使用控制反轉(IOC) 模式將應用程序的配置和依賴性規(guī)范與實際的應用程序代碼分開。
- Spring 上下文:Spring 上下文是一個配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企業(yè)服務,例如 JNDI、EJB、電子郵件、國際化、校驗和調度功能。
- Spring AOP:通過配置管理特性,Spring AOP 模塊直接將面向切面的編程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的對象。Spring AOP 模塊為基于 Spring 的應用程序中的對象提供了事務管理服務。通過使用 Spring AOP,不用依賴組件,就可以將聲明性事務管理集成到應用程序中。
- Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結構,可用該結構來管理異常處理和不同數據庫供應商拋出的錯誤消息。異常層次結構簡化了錯誤處理,并且極大地降低了需要編寫的異常代碼數量(例如打開和關閉連接)。Spring DAO 的面向 JDBC 的異常遵從通用的 DAO 異常層次結構。
- Spring ORM:Spring 框架插入了若干個 ORM 框架,從而提供了 ORM 的對象關系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有這些都遵從 Spring 的通用事務和 DAO 異常層次結構。
- Spring Web 模塊:Web 上下文模塊建立在應用程序上下文模塊之上,為基于 Web 的應用程序提供了上下文。所以,Spring 框架支持與 Jakarta Struts 的集成。Web 模塊還簡化了處理多部分請求以及將請求參數綁定到域對象的工作。
- Spring MVC 框架:MVC 框架是一個全功能的構建 Web 應用程序的 MVC 實現。通過策略接口,MVC 框架變成為高度可配置的,MVC 容納了大量視圖技術,其中包括 JSP、Velocity、Tiles、iText 和 POI。
二、Spring之IOC詳解
2.1.IOC理論推導
我們先新建一個Maven項目來進行我們的IOC理論推導
2.1.1.IOC分析實現
給客戶添加一個文件上傳的接口,實現文件上傳的功能
1.建立一個UserService接口
public interface UserService {
public void update();
}
2.實現接口完成功能
public class UserServiceImpl implements UserService {
public void update() {
System.out.println("V1.0:程序員實現功能完寫的實現類");
}
}
3.客戶要求更改需求
public class UserServiceImpl2 implements UserService {
public void update() {
System.out.println("V2.0:解決客戶投訴問題,更改需求");
}
}
4.編寫Userservlet
public class UserAction {
private UserService userService= new UserServiceImpl2();
public String Update(){
userService.update();
return "list";
}
}
在公司很多時候客戶在上午提的需求,你做完了下午就不要了,那你只能修改UserServlet的接口實現把2變?yōu)?,一個類修改起來容易,10..50..100..這種方式就根本不適用, 甚至反人類?, 每次變動 , 都需要修改大量代碼 . 這種設計的耦合性太高了, 牽一發(fā)而動全身 。
如果使用Spring, 以前所有東西都是由程序去進行控制創(chuàng)建 ,?而現在是由我們自行控制創(chuàng)建對象 , 把主動權交給了調用者 。?程序不用去管怎么創(chuàng)建,怎么實現,它只負責提供一個接口 。
2.1.2.IOC本質
控制反轉IOC(Inversion of Control),是一種設計思想,DI(依賴注入)是實現IOC的一種方法,也有人認為DI只是IOC的另一種說法。沒有IOC的程序中 , 我們使用面向對象編程 , 對象的創(chuàng)建與對象間的依賴關系完全硬編碼在程序中,對象的創(chuàng)建由程序自己控制,控制反轉后將對象的創(chuàng)建轉移給第三方,個人認為所謂控制反轉就是:獲得依賴對象的方式反轉了。
耦合對象:
?解耦對象:
理想系統(tǒng):
IOC是Spring框架的核心內容,使用多種方式完美的OC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配IOC。
Spring容器在初始化時先讀取配置文件,根據配置文件或元數據創(chuàng)建與組織對象存入容器中,程序使用時再從Ioc容器中取出需要的對象。
采用XML方式配置Bean的時候,Bean的定義信息是和實現分離的,而采用注解的方式可以把兩者合為一體,Bean的定義信息直接以注解的形式定義在實現類中,從而達到了零配置的目的。
控制反轉是一種通過描述(XML或注解)并通過第三方去生產或獲取特定對象的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入(Dependency Injection,DI)。
2.2.Maven項目導入Jar包
spring 需要導入commons-logging進行日志記錄 ,?我們利用maven ,他會自動下載對應的依賴項?
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>
2.3.依賴注入
2.3.1.Set注入(重點)
userAction.java
public class UserAction {
private UserService userService;
private String name;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public List<String> getHobbys() {
return hobbys;
}
public void setHobbys(List<String> hobbys) {
this.hobbys = hobbys;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String Update(){
userService.update();
System.out.println("名字:"+name);
System.out.println("書籍:");
for (String book:books){
System.out.print("<<"+book+">>\t\n");
}
System.out.println("愛好:"+hobbys);
System.out.println("card:"+card);
System.out.println("games:"+games);
return "list";
}
}
GoodsAction.java
public class GoodsAction {
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String Update(){
userService.update();
return "list";
}
}
Test測試類
public class UserTest {
public static void main(String[] args) {
//加載spring核心配置文件(建模)獲取spring的上下文對象
//上下文對象中可以獲取任何Javabean對象
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml");
//用戶
UserAction useraction = (UserAction) context.getBean("userAction");
useraction.Update();
System.out.println(" ===============================");
//商品
GoodsAction goodsAction= (GoodsAction) context.getBean("goodsAction");
goodsAction.Update();
}
1.Bean注入
這里的值是一個引用,ref
<bean class="com.csdn.xw.web.UserAction" id="userAction">
<property name="userService" ref="serviceImpl2"></property>
<property name="name" value="小明"></property>
</bean>
<bean class="com.csdn.xw.service.impl.UserServiceImpl2" id="serviceImpl2"></bean>
2.數組注入
<property name="books" >
<array>
<value>西游記</value>
<value>紅樓夢</value>
<value>水滸傳</value>
<value>三國演義</value>
</array>
</property>
3.List注入
<property name="hobbys">
<list>
<value>唱</value>
<value>跳</value>
<value>RAP</value>
</list>
</property>
4.Map注入
<property name="card">
<map>
<entry key="JAVA" value="100"></entry>
<entry key="Python" value="100"></entry>
</map>
</property>
5.Set注入
<property name="games">
<set>
<value>電腦</value>
<value>鼠標</value>
</set>
</property>
測試結果:
2.3.2.構造注入
無參構造創(chuàng)建對象
userAction.java
public class UserAction {
public UserAction() {
System.out.println("user創(chuàng)建了");
}
}
spring-context.xml
<bean class="com.csdn.xw.web.UserAction" id="UserAction"></bean>
測試結果:
有參構造創(chuàng)建對象
userAction.java
public class UserAction {
private String name;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
//有參構造器
public UserAction(String name, String[] books, List<String> hobbys, Map<String, String> card, Set<String> games) {
this.name = name;
this.books = books;
this.hobbys = hobbys;
this.card = card;
this.games = games;
}
/測試有無注入
public void pros(){
System.out.println("名字:"+name);
System.out.println("書籍:");
for (String book:books){
System.out.print("<<"+book+">>\t\n");
}
System.out.println("愛好:"+hobbys);
System.out.println("card:"+card);
System.out.println("games:"+games);
}
}
spring-context.xml
<bean class="com.csdn.xw.web.UserAction" id="userAction">
<property name="userService" ref="serviceImpl2"></property>
<constructor-arg name="name" value="張三"></constructor-arg>
<constructor-arg name="books">
<array>
<value>大話數據結構</value>
<value>大話設計模式</value>
</array>
</constructor-arg>
<constructor-arg name="hobbys">
<list>
<value>沐浴</value>
<value>足療</value>
<value>按摩</value>
</list>
</constructor-arg>
<constructor-arg name="card">
<map>
<entry key="csdn" value="nb"></entry>
</map>
</constructor-arg>
<constructor-arg name="games">
<set>
<value>Java方文山</value>
</set>
</constructor-arg>
</bean>
測試結果:
2.4.自動裝配
byName(按名稱自動裝配)
由于在手動配置xml過程中,常常發(fā)生字母缺漏和大小寫等錯誤,而無法對其進行檢查,使得開發(fā)效率降低。采用自動裝配將避免這些錯誤,并且使配置簡單化。
測試:
1、修改bean配置,增加一個屬性 autowire=“byName”
<bean class="com.csdn.xw.web.GoodsAction" id="goodsActiona" autowire="byName">
<property name="userService" ref="serviceImpl1"></property>
</bean>
<beans xmlns="http://www.springframework.org/schema/beans"
default-autowire="byName"
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">
2、再次測試,結果依舊成功輸出!
3、我們將 GoodsAction的bean id修改為 goodsACtion
4、再次測試, 執(zhí)行時報空指針java.lang.NullPointerException。因為按byName規(guī)則找不對應set方法,真正的setgoodsAction就沒執(zhí)行,對象就沒有初始化,所以調用時就會報空指針錯誤。
小結:
當一個bean節(jié)點帶有 autowire byName的屬性時
或是beans節(jié)點帶有?default-autowire="byName"。
-
將查找其類中所有的set方法名,例如setCat,獲得將set去掉并且首字母小寫的字符串,即cat。
-
去spring容器中尋找是否有此字符串名稱id的對象。
-
如果有,就取出注入;如果沒有,就報空指針異常。
byType?(按類型自動裝配)
使用autowire byType首先需要保證:同一類型的對象,在spring容器中唯一。如果不唯一,會報不唯一的異常。
NoUniqueBeanDefinitionException
測試:
1、將user的bean配置修改一下 : autowire=“byType”
2、測試,正常輸出
3、在注冊一個goodsAction的bean對象!
<bean class="com.csdn.xw.web.GoodsAction" id="goodsAction" autowire="byType">
</bean>
<bean class="com.csdn.xw.web.UserAction" id="userAction" autowire="byType">
<property name="userService" ref="serviceImpl2"></property>
</bean>
<bean class="com.csdn.xw.service.impl.UserServiceImpl2" id="serviceImpl2"></bean>
<bean class="com.csdn.xw.service.impl.UserServiceImpl1" id="serviceImpl1"></bean>
4、測試,報錯:NoUniqueBeanDefinitionException
5、在這個配置中,我們定義了兩個UserService的實現類?UserServiceImpl1和?UserServiceImpl2,并且將UserAction的autowire屬性設置為byType,表示使用byType進行自動裝配。
現在,如果我們運行這個程序,將會拋出一個異常,提示存在多個匹配的 bean,無法確定要注入哪個 bean。這是因為?UserAction類依賴于UserService接口,而容器中存在兩個與?UserService接口匹配的 bean,即?UserServiceImpl1和?UserServiceImpl2,導致無法確定要注入哪個 bean。
這就是按照類型自動裝配!
2.5.spring與web容器的整合
每一次的請求都需要進行建模,十分消耗新能,希望建模一次,然后每次的請求都可以拿到spring的上下文。使用監(jiān)聽器將spring上下文放入tomcat上下文中。
SpringLoadlistener.java
@WebListener
public class SpringLoadlistener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
System.out.println("初始化將Spring的上下文放入tomcat");
//將Spring的上下文放入tomcat
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("/Spring-Context.xml");
//獲取tomcat上下文
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("springcontext",context);
}
}
UserServlet.java
@WebServlet("/userlist")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//處理請求的時候獲取spring上下文
ClassPathXmlApplicationContext springcontext = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("springcontext");
UserAction useraction = (UserAction) springcontext.getBean("userAction");
System.out.println(useraction);
useraction.Update();
}
}
測試結果:
?到這里我的分享就結束了,歡迎到評論區(qū)探討交流??!
如果覺得有用的話還請點個贊吧??? ?文章來源:http://www.zghlxwxcb.cn/news/detail-665682.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-665682.html
到了這里,關于Spring框架之一文讀懂Spring IOC從演變到自動裝配的全攻略的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!