膠州國際網(wǎng)站建設(shè)效果賺錢平臺(tái)
一、簡(jiǎn)介
1、什么是spring?
Spring是一個(gè)開源的輕量級(jí)Java應(yīng)用開發(fā)框架,它提供了一種簡(jiǎn)單、高效、靈活的方式來構(gòu)建企業(yè)級(jí)應(yīng)用程序。Spring框架的核心特點(diǎn)是依賴注入(Dependency Injection)和面向切面編程(Aspect-Oriented Programming),它通過一組模塊化的組件提供全面的支持,使開發(fā)人員能夠快速搭建可擴(kuò)展、可維護(hù)的應(yīng)用。
2、目的
學(xué)習(xí)Spring的目的可以總結(jié)為以下幾點(diǎn):
- 簡(jiǎn)化開發(fā):Spring提供了一系列的工具和抽象,簡(jiǎn)化了企業(yè)級(jí)應(yīng)用開發(fā)過程。它通過依賴注入來解決對(duì)象間的依賴關(guān)系,使得代碼更加靈活、可測(cè)試和可維護(hù)。
- 高效開發(fā):Spring框架提供了諸多模塊,如Spring MVC、Spring Boot等,可以快速構(gòu)建Web應(yīng)用和微服務(wù)。它提供了一種約定優(yōu)于配置的開發(fā)方式,提高了開發(fā)效率。
- 提高可擴(kuò)展性:Spring框架基于接口和模塊化設(shè)計(jì),能夠方便地集成其他開源框架和庫。它的松耦合特性使得應(yīng)用程序更易于擴(kuò)展和維護(hù)。
- 豐富的功能:Spring擁有豐富的功能和特性,包括事務(wù)管理、安全性、緩存、消息隊(duì)列、調(diào)度等。它為開發(fā)人員提供了一系列解決方案,使得應(yīng)用程序開發(fā)更加便捷。
3、功能及使用范圍
Spring的功能范圍非常廣泛,包括但不限于以下方面:
- 依賴注入和控制反轉(zhuǎn):通過依賴注入,Spring容器能夠?qū)?duì)象之間的依賴關(guān)系管理起來,使得對(duì)象的創(chuàng)建和使用解耦,提高代碼的靈活性和可測(cè)試性。
- 面向切面編程:Spring提供了面向切面編程(AOP)的支持,可以將與核心業(yè)務(wù)邏輯無關(guān)的功能(如事務(wù)管理、日志記錄等)進(jìn)行橫切,提高了代碼的重用性和可維護(hù)性。
- Web開發(fā)支持:Spring提供了Spring MVC模塊,用于開發(fā)Web應(yīng)用程序。它能夠處理HTTP請(qǐng)求和響應(yīng),進(jìn)行URL路由、數(shù)據(jù)綁定、表單驗(yàn)證、視圖解析等操作,簡(jiǎn)化了Web開發(fā)過程。
- 數(shù)據(jù)訪問支持:Spring框架提供了對(duì)各種數(shù)據(jù)訪問技術(shù)的支持,包括JDBC、ORM(如Hibernate、MyBatis)、JPA等。它通過抽象出一套統(tǒng)一的數(shù)據(jù)訪問接口,使得數(shù)據(jù)庫訪問更加方便和可替換。
- 安全性支持:Spring提供了一套強(qiáng)大的安全性框架,可以進(jìn)行認(rèn)證和授權(quán)管理。它支持各種身份驗(yàn)證方式,如基于表單的認(rèn)證、基于角色的訪問控制等,保護(hù)應(yīng)用程序的安全性。
總之,Spring框架是Java開發(fā)領(lǐng)域最流行的框架之一,它提供了豐富的功能和特性,幫助開發(fā)人員構(gòu)建可靠、高效的企業(yè)級(jí)應(yīng)用程序。
一句話概括,Spring是一個(gè)輕量級(jí)的控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架。
二、spring IOC
1、ioc的理解
IoC(Inversion of Control,控制反轉(zhuǎn))是Spring框架的核心概念之一,也是實(shí)現(xiàn)依賴注入的基礎(chǔ)。它通過解耦對(duì)象之間的依賴關(guān)系,使得對(duì)象的創(chuàng)建和管理由框架來負(fù)責(zé),而不是由開發(fā)人員手動(dòng)管理。
在傳統(tǒng)的程序設(shè)計(jì)中,對(duì)象之間的依賴關(guān)系通常由開發(fā)人員在代碼中進(jìn)行硬編碼,對(duì)象直接通過關(guān)鍵字(如new)來創(chuàng)建和管理。這種方式存在一些問題,如對(duì)象之間的耦合度高、可測(cè)試性差、擴(kuò)展性差等。
而IoC則是一種思想上的轉(zhuǎn)變,它將對(duì)象的創(chuàng)建和管理權(quán)利交給了框架。具體來說,IoC的核心思想是:通過配置或注解,告訴框架需要?jiǎng)?chuàng)建哪些對(duì)象,以及對(duì)象之間的依賴關(guān)系。然后,框架在應(yīng)用程序運(yùn)行時(shí)根據(jù)配置信息動(dòng)態(tài)地創(chuàng)建和組裝對(duì)象。
Spring通過IoC容器來實(shí)現(xiàn)控制反轉(zhuǎn)。IoC容器是一個(gè)用于管理對(duì)象的容器,它負(fù)責(zé)創(chuàng)建、組裝、初始化和銷毀對(duì)象。開發(fā)人員只需要配置對(duì)象的創(chuàng)建和依賴關(guān)系,然后通過容器來獲取需要的對(duì)象即可。
使用Spring的IoC容器,開發(fā)人員可以達(dá)到以下幾個(gè)目的:
- 解耦對(duì)象之間的依賴關(guān)系:通過IoC容器,開發(fā)人員只需要關(guān)注對(duì)象的功能實(shí)現(xiàn),而不需要關(guān)心對(duì)象是如何創(chuàng)建和組裝的。對(duì)象之間的依賴關(guān)系由容器負(fù)責(zé)管理,降低了對(duì)象之間的耦合度。
- 提高代碼的可測(cè)試性:由于對(duì)象的創(chuàng)建和組裝由容器來完成,開發(fā)人員可以很容易地對(duì)對(duì)象進(jìn)行替換或模擬,從而實(shí)現(xiàn)單元測(cè)試和集成測(cè)試。
- 增強(qiáng)代碼的可擴(kuò)展性:當(dāng)需要添加新的功能或模塊時(shí),只需要配置新的對(duì)象和依賴關(guān)系,而不需要修改現(xiàn)有的代碼。通過配置方式,可以方便地在不影響現(xiàn)有代碼的情況下進(jìn)行擴(kuò)展。
- 提高代碼的靈活性:IoC容器使得對(duì)象的創(chuàng)建完全可配置化,可以在運(yùn)行時(shí)根據(jù)需要?jiǎng)?chuàng)建不同的實(shí)例。同時(shí),框架提供了生命周期管理和依賴解析等功能,使得對(duì)象的管理更加便捷。
總而言之,IoC是Spring框架的核心特性之一,它通過控制反轉(zhuǎn)的思想,將對(duì)象的創(chuàng)建和依賴關(guān)系的管理交給了框架,減少了對(duì)象之間的耦合度,提高了代碼的可測(cè)試性和可擴(kuò)展性。
2、分析實(shí)現(xiàn)
首先創(chuàng)建好我們的maven項(xiàng)目
?設(shè)置我們的pom.xml
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!-- 2、導(dǎo)入spring依賴 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><!-- 5.1、junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency><!-- 5.2、servlet --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>${javax.servlet.version}</version><scope>provided</scope></dependency>
新建
我們用原來的方式寫一下
- 編寫一個(gè)接口
public interface UserService {public void updUser(); }
- 再編寫一個(gè)實(shí)現(xiàn)類
public class UserServiceImpl1 implements UserService {public void updUser() {System.out.println("修改SQL用戶數(shù)據(jù)"); }
我們?cè)瓉淼姆绞绞沁@樣寫的
-
現(xiàn)在我們添加一個(gè)實(shí)現(xiàn)類
public class UserServiceImpl2 implements UserService {public void updUser() {System.out.println("修改SQL用戶數(shù)據(jù)");//修改用戶姓名System.out.println("修改用戶姓名");} }
-
當(dāng)我們測(cè)試調(diào)方法的時(shí)候只需要改動(dòng)后面的實(shí)現(xiàn)類
-
手動(dòng)實(shí)例化的弊端:
1、一旦依賴的接口實(shí)現(xiàn)需要大批量改動(dòng),迭代,維護(hù)成本高
?2、當(dāng)接口的實(shí)現(xiàn)類不統(tǒng)一,維護(hù)成本更高
我們?cè)趺唇鉀Q這個(gè)問題呢?
3、編寫bean
首先我們要在maven項(xiàng)目里面的resources文件里面建立一個(gè)基于spring的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>
?我們?cè)趙eb文件里面建立兩個(gè)Class類
public class UserAction {private UserService us;public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}}
public class GoodsAction {private UserService us;public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}}
編寫一個(gè)測(cè)試類
public class demo1 {public static void main(String[] args) { // 加載spring核心配置文件(建模),獲取spring的上下文對(duì)象,上下文對(duì)象中可以獲取任何JavaBean對(duì)象ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");UserAction userAction = (UserAction) context.getBean("userAction");userAction.updUser();GoodsAction goodsAction = (GoodsAction) context.getBean("goodsAction");goodsAction.updUser();} }
在我們的新建的這個(gè)spring-context.xml文件里面添加<bean>
<?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"><!--凡是在spring核心配置文件spring-context.xml中配置,那么該類JavaBean就交給了spring容器管理--><bean class="com.tgq.ioc.web.UserAction" id="userAction"><property name="us" ref="userService1"/></bean><bean class="com.tgq.ioc.web.GoodsAction" id="goodsAction"><property name="us" ref="userService2"/></bean><bean class="com.tgq.ioc.service.impl.UserServiceImpl1" id="userService1"/><bean class="com.tgq.ioc.service.impl.UserServiceImpl2" id="userService2"/> </beans>
?
三、spring IOC的注入方式
spring的ioc有哪些注入方式呢?
- set方法屬性注入
- 構(gòu)造注入
- 接口注入/自動(dòng)裝配
1、set方法屬性注入
在我們前面的GoodsAction新添幾個(gè)屬性和get、set方法,一個(gè)輸出打印的方法toPrint()
public class GoodsAction {private UserService us;private String name;private int age;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;}public List<String> getPeoples() {return peoples;}public void setPeoples(List<String> peoples) {this.peoples = peoples;}private List<String> peoples;public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}public void toPrint() {System.out.println(this.name);System.out.println(this.age);System.out.println(this.peoples);}}
在print-context.xml里面設(shè)置值,使用set方法屬性注入用property
<bean class="com.tgq.ioc.web.GoodsAction" id="goodsAction"><property name="us" ref="userService2"></property><property name="name" value="旺財(cái)"/><property name="age" value="20"/><property name="peoples"><list><value>留守兒童</value><value>情侶</value><value>留守老人</value></list></property></bean>
在測(cè)試類里面調(diào)用
goodsAction.toPrint();
?
2、構(gòu)造注入
在我們的User Action里面添加屬性及有參無參的構(gòu)造方法,一個(gè)輸出打印的方法toPrint()
public class UserAction {private UserService us;private String name;private int age;private List<String> hobby;public UserAction() {}public UserAction(String name, int age, List<String> hobby) {this.name = name;this.age = age;this.hobby = hobby;}public UserService getUs() {return us;}public void setUs(UserService us) {this.us = us;}public String updUser() {us.updUser();return "list";}public void toPrint() {System.out.println(this.name);System.out.println(this.age);System.out.println(this.hobby);} }
在print-context.xml里面設(shè)置值,使用構(gòu)造輸入需要用constructor-arg標(biāo)簽
<bean class="com.tgq.ioc.web.UserAction" id="userAction"><property name="us" ref="userService1"/><constructor-arg name="name" value="l"/><constructor-arg name="age" value="18"/><constructor-arg name="hobby"><list><value>唱</value><value>跳</value><value>rap</value></list></constructor-arg></bean>
繼續(xù)在測(cè)試類里面調(diào)用toPrint方法
?
?
3、自動(dòng)裝配
自動(dòng)裝配中byName和byType的區(qū)別:
byName:在配置好的文件中變量名不更改就不會(huì)報(bào)錯(cuò)。按照屬性的名稱進(jìn)行自動(dòng)裝配。
- 當(dāng)一個(gè)bean的屬性名稱與其他bean的id匹配時(shí),Spring容器會(huì)自動(dòng)將該bean注入到對(duì)應(yīng)的屬性中。
- 如果找不到匹配的bean,則會(huì)拋出異常。
- 在XML配置中,可以使用
autowire="byName"
或@Autowired
注解實(shí)現(xiàn)byName自動(dòng)裝配。byType:會(huì)在整個(gè)spring中尋找JavaBean,按照屬性的類型進(jìn)行自動(dòng)裝配。
- 當(dāng)一個(gè)bean的屬性的類型與其他bean的class匹配時(shí),Spring容器會(huì)自動(dòng)將該bean注入到對(duì)應(yīng)的屬性中。
- 如果有多個(gè)匹配的bean,則會(huì)拋出異常,需要進(jìn)行更具體的限定或使用
@Qualifier
注解來解決。- 在XML配置中,可以使用
autowire="byType"
或@Autowired
注解實(shí)現(xiàn)byType自動(dòng)裝配。
四、spring與tomcat的整合/spring與web容器的整合
我們的xml文件
<?xml version="1.0" encoding="UTF-8"?> <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"><!--凡是在spring核心配置文件spring-context.xml中配置,那么該類JavaBean就交給了spring容器管理--><bean class="com.tgq.ioc.web.UserAction" id="userAction"><property name="us" ref="userService1"/></bean><bean class="com.tgq.ioc.web.GoodsAction" id="goodsAction"><property name="us" ref="userService2"/></bean><bean class="com.tgq.ioc.service.impl.UserServiceImpl1" id="userService1"/><bean class="com.tgq.ioc.service.impl.UserServiceImpl2" id="userService2"/> </beans>
編寫一個(gè)過濾器
@WebListener public class sprintListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("初始化");//spring的上下文ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); //tomcat上下文ServletContext servletContext = sce.getServletContext();servletContext.setAttribute("sprintContext", context);} }
編寫servlet類調(diào)用它
@WebServlet("userlist") public class Userservlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//獲取到sprint的上下文對(duì)象ClassPathXmlApplicationContext Context = (ClassPathXmlApplicationContext) req.getServletContext().getAttribute("sprintContext");UserService bean = (UserService) Context.getBean("userService1");System.out.println(bean);bean.updUser();} }
啟動(dòng)服務(wù)器就完成了整合
?