spring超全面详解
spring概述
Spring 是于2003年興起的一款輕量級(jí)的,非侵入式的IOC和AOP的一站式的java開發(fā)框架? 為簡(jiǎn)化企業(yè)級(jí)應(yīng)用開發(fā)而生. 1.輕量級(jí):? ?就是指spring核心功能的jar包不大 2.非侵入式:??我們的業(yè)務(wù)代碼不需要繼承或?qū)崿F(xiàn)spring中任何的類或接口 3.IOC:? ?控制反轉(zhuǎn)? ? 就是把創(chuàng)建對(duì)象的權(quán)利反轉(zhuǎn)給spring框架 4.AOP:? 面向切面編程? ? 它是一種編程思想,是面向?qū)ο缶幊?#xff08;OOP) 的一種補(bǔ)充。面向?qū)ο缶幊虒⒊绦虺橄蟪筛鱾€(gè)層次的對(duì)象,而面向切面編程是將程序抽象成各個(gè)切面 5.一站式框架:? ?Spring 本身也提供了數(shù)據(jù)訪問(wèn)功能和 web 功能,以及可以很好的管理其他框架
Spring 體系結(jié)構(gòu)
Core Container(核心容器): Beans:? ? ?管理 Beans Core:? ? ? ?Spring 的核心,提供IOC容器的對(duì)象的創(chuàng)建并處理依賴對(duì)象關(guān)系 Context:? 配置文件? 就是Bean的關(guān)系的集合,也叫做IOC容器,調(diào)用了大部分spring-core中的方法 ExpressionLanguage: SpEL 表達(dá)式 AOP:? ? 切面編程? ?使?Spring框架管理對(duì)象支持AOP,同時(shí)這個(gè)模塊也提供了事務(wù)管理 ORM:? ?提供了對(duì)現(xiàn)有的ORM框架的支持,例如Hibernate,JDO,Mybatis等。 DAO:? ? 提供了對(duì)數(shù)據(jù)訪問(wèn)對(duì)象(Data Access Object,DAO)模式和JDBC的支持,把實(shí)現(xiàn)業(yè)務(wù)邏輯和數(shù)據(jù)庫(kù)訪問(wèn)的代碼實(shí)現(xiàn)分離等。 Data Access(數(shù)據(jù)庫(kù)整合): JDBC, ORM, OXM, JMS, Transaction springWeb(MVC Web 開發(fā)):??是 spring 框架的一個(gè)模塊,springWeb 和 spring 無(wú)需通過(guò)中間整合層進(jìn)行整合,? ?是一個(gè)基于 mvc 的 web 框架,方便前后端數(shù)據(jù)的傳輸,? ??擁有控制器,接收外部求,解析參數(shù)傳給服務(wù)層spring搭建和測(cè)試
spring項(xiàng)目的搭建就是在Maven項(xiàng)目的基礎(chǔ)上添加一些依賴并且進(jìn)行一些配置
1.Maven 導(dǎo)入 spring 核心基礎(chǔ) jar
<!-- spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency> 2.編寫 spring 配置文件 <?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"> <bean id="admin" class="com.ffyc.spring.bean.Admin"> </bean> </beans> 3.編寫一個(gè) Admin 實(shí)體類 public class Admin {private int id;private String account;public Admin() {System.out.println("無(wú)參構(gòu)造方法");}public Admin(int id, String account) {this.id = id;this.account = account;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getAccount() {return account;}public void setAccount(String account) {this.account = account;}@Overridepublic String toString() {return "Admin{" +"id=" + id +", account='" + account + '\'' +'}';} }4.測(cè)試
//讀取spring配置文件,并對(duì)文件中配置的對(duì)象進(jìn)行創(chuàng)建ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");Admin admin = app.getBean("admin", Admin.class);System.out.println(admin);IOC(控制反轉(zhuǎn))
概述:? 它是一種設(shè)計(jì)思想,就是將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán),交由 Spring 框架來(lái) 管理。 IOC 容器是具有依賴注入功能的容器,負(fù)責(zé)對(duì)象的實(shí)例化、對(duì)象的初始化,對(duì)象和對(duì)象之間依賴關(guān)系配置、對(duì)象的銷毀、對(duì)外提供對(duì)象的查找等操作,對(duì)象的整個(gè)生命周期都是由容器來(lái)控制。我們需要使用的對(duì)象都由 ioc 容器進(jìn)行管 理,不需要我們?cè)偃ナ謩?dòng)通過(guò) new 的方式去創(chuàng)建對(duì)象,由 ioc 容器直接幫我們組裝好,當(dāng)我們需要使用的時(shí)候直接從 ioc 容器中直接獲取就可以了。 正控:若要使用某個(gè)對(duì)象,需要自己去負(fù)責(zé)對(duì)象的創(chuàng)建 反控:若要使用某個(gè)對(duì)象,只需要從 Spring 容器中獲取需要使用的對(duì)象,不關(guān)心對(duì)象的創(chuàng)建過(guò)程,也就是把創(chuàng)建對(duì)象的控制權(quán)反轉(zhuǎn)給了 Spring 框架. 底層實(shí)現(xiàn)方式: 解析 xml/掃描注解標(biāo)簽 + 工廠模式 + 反射機(jī)制spring中bean的管理
1.基于 xml 配置方式依賴注入
在spring創(chuàng)建對(duì)象(控制反轉(zhuǎn))時(shí),還需要為我們的對(duì)象屬性進(jìn)行初始化賦值,這個(gè)過(guò)程稱為依賴注入
(1)get,? set? 方式注入
<bean id="admin" name="admin2" class="com.ffyc.ssm.model.Admin" scope="prototype"><property name="id" value="10"></property><property name="account" value="admin"></property></bean>(2)構(gòu)造方法注入
<bean id="admin" name="admin1" class="com.ffyc.ssm.model.Admin" scope="prototype"><constructor-arg name="id" value="100"></constructor-arg><constructor-arg name="account" value="admins"></constructor-arg></bean> bean 配置需要 spring 管理的類,也叫做spring管理的類叫做bean對(duì)象 id 生成的對(duì)象名 class 全類名 name 對(duì)象別名,可以為多個(gè) scope(bean的作用域): singleton(默認(rèn)值):在 Spring 中只存在一個(gè) bean 實(shí)例, 單例模式.? 在spring啟動(dòng)時(shí)就會(huì)創(chuàng)建 prototype:原型 getBean()的時(shí)候都會(huì) new Bean() 2.注解方式實(shí)現(xiàn)依賴注入 (1)注解需要的 jar 包,? 注解功能封裝在 AOP 包中,導(dǎo)入 Spring aop jar 包即可 <dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version> </dependency>(2)在spring中開啟注解掃描
<context:component-scan base-package="包名"> </context:component-scan> (3)利用注解方式創(chuàng)建對(duì)象 @Component(value=“admin”)也就是相當(dāng)于?<bean id=“admin” class=“”></bean> @Service @Repository 以上注解都可以實(shí)現(xiàn)創(chuàng)建對(duì)象功能,只是為了后續(xù)擴(kuò)展功能,在不同的層使用不同的注解標(biāo)記 @Scope(value=“prototype”) 原型? ? ? ? ?@Scope(value=“ singleton ”) 單例 3.注解方式注入屬性 (1)@Autowired @Autowired 是 Spring 提供的注解,有兩種方式進(jìn)行注入 byType 自動(dòng)注入 該注解默認(rèn)使用按類型自動(dòng)裝配 Bean 的方式。 byName 自動(dòng)注入 如果我們想使用按照名稱(byName)來(lái)裝配,可以結(jié)合@Qualifier 注解一起使用。 需要在引用屬性上聯(lián)合使用注解@Autowired 與@Qualifier。@Qualifier 的value 屬性用于指定要匹配的 Bean 的 id 值。 @Autowired @Qualifier(value = "adminDao")AdminDao adminDao; (2)@Resource 自動(dòng)注入 Spring 提供了對(duì) jdk 中@Resource 注解的支持。 @Resource 注解既可以按名稱匹配 Bean,也可以按類型匹配 Bean。默認(rèn)按照 ByType 自動(dòng)注入 byName 注入引用類型屬性 @Resource 注解指定其 name 屬性,則 name 的值即為按照名稱進(jìn)行匹配的 Bean 的 id。 @Resource(name = "adminDao")AdminDao adminDao;4.注解與 XML 的對(duì)比
注解優(yōu)點(diǎn): 方便,直觀,高效(代碼少,沒(méi)有配置文件的書寫那么復(fù)雜) 注解缺點(diǎn):以硬編碼的方式寫入到 Java 代碼中,修改是需要重新編譯代碼的。 xml 優(yōu)點(diǎn)是: 配置和代碼是分離的,在 xml 中做修改,無(wú)需編譯代碼,只需重啟服務(wù)器即可將新的配置加載。 xml 的缺點(diǎn)是:編寫麻煩,效率低,大型項(xiàng)目過(guò)于復(fù)雜。Spring JDBC
Spring 是個(gè)一站式框架:Spring 自身也提供了控制層的 SpringMVC 和 持久層的 Spring JdbcTemplate。 搭建步驟: 1.下載 Spring JdbcTemplate 的 jar 包 <!-- spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.2.RELEASE</version> </dependency> 2.導(dǎo)入阿里巴巴提供的數(shù)據(jù)源管理組件 ?druid(德魯伊) ? ? 常用的數(shù)據(jù)庫(kù)連接池組件:dbcp c3p0 數(shù)據(jù)源組件,封裝了連接數(shù)據(jù)庫(kù),還有數(shù)據(jù)庫(kù)連接池功能 <!-- 阿里數(shù)據(jù)源 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> 3.導(dǎo)入屬性文件(config.properties) classDriverName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai uname=root pwd=root <context:property-placeholder location="config.properties"/> 4.管理數(shù)據(jù)源對(duì)象 spring 管理與數(shù)據(jù)庫(kù)鏈接 (數(shù)據(jù)源) <bean id="dataSource"class="com.alibaba.druid.pool.DruidDataSource"> <propertyname="driverClassName" value="${driverClassName}"></property> <property name="url" value="${url}"></property> <property name="username" value="${uname}"></property> <property name="password" value="${pwd}"></property> <property name="initialSize" value="10"></property> <property name="minIdle" value="5"></property> <property name="maxActive" value="20"></property> </bean> 5.創(chuàng)建spring封裝的jdbc <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><!--注入數(shù)據(jù)源的對(duì)象--><property name="dataSource" ref="dataSource"></property></bean>6.在類中獲得 JdbcTemplate 對(duì)象,直接使用。
?
?
AOP(面向切面編程)
前言:? ???開發(fā)好一個(gè)版本后,后期如果需要添加新的功能,就需要修改原來(lái)的代碼,加入調(diào)用新功能的代碼.? 這樣開發(fā)就很麻煩,會(huì)存在大量的冗余代碼.
概述:??AOP為Aspect Oriented Programming的縮寫 面向切面編程,? 它是 OOP 的延續(xù),可以對(duì)業(yè)務(wù)邏輯和非業(yè)務(wù)邏輯進(jìn)行隔離,從而使得各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。 AOP、OOP 是面向不同領(lǐng)域的兩種設(shè)計(jì)思想。OOP (面向?qū)ο缶幊?#xff09;針對(duì)業(yè)務(wù)處理過(guò)程的實(shí)體及其屬性和行為進(jìn)行抽象封裝,以獲得更加清晰高效的邏輯單元?jiǎng)澐帧?而 AOP 則是針對(duì)業(yè)務(wù)處理過(guò)程中的切面進(jìn)行提取,它所面對(duì)的是處理過(guò)程中的某個(gè)步驟或階段,以獲得邏輯過(guò)程中各部分之間低耦合性的隔離效果。
也就是將程序中的一些非業(yè)務(wù)代碼進(jìn)行提取,在不需要修改原來(lái)代碼的情況下,為程序添加額外的功能.
非業(yè)務(wù)代碼:??(驗(yàn)證權(quán)限,打印日志,提交事務(wù),統(tǒng)一異常處理)
核心原理: 使用動(dòng)態(tài)代理的方式在執(zhí)行方法前后或者出現(xiàn)異常的時(shí)候做加入相關(guān)的邏輯.
使用案例: 事務(wù)處理:開啟事務(wù),關(guān)閉事務(wù),出現(xiàn)異常后回滾事務(wù) ? ? ? ? ? ? ? ? 權(quán)限判斷:在執(zhí)行方法前,判斷是否具有權(quán)限 ? ? ? ? ? ? ? ? 日志:在執(zhí)行前進(jìn)行日志處理?AOP 的基本概念
連接點(diǎn)(Joinpoint):類中可以被增強(qiáng)的方法,這個(gè)方法就被稱為連接點(diǎn) 切入點(diǎn)(pointcut):類中有很多方法可以被增強(qiáng),但實(shí)際中只有 add 和 update被增強(qiáng)了,那么 add 和 update 方法就被稱為切入點(diǎn)(實(shí)際實(shí)現(xiàn)的連接點(diǎn)) 通知(Advice): 通知是指一個(gè)切面在特定的連接點(diǎn)要做的事情(增強(qiáng)的功能)。通知分為方法執(zhí)行前通知,方法執(zhí)行后通知,環(huán)繞通知等. 切面(Aspect):把通知添加到切入點(diǎn)的整個(gè)過(guò)程稱為切面. 目標(biāo)(Target): 代理的目標(biāo)對(duì)象(連接點(diǎn),切入點(diǎn)所在類) 代理(Proxy): 向目標(biāo)對(duì)象應(yīng)用通知時(shí)創(chuàng)建的代理對(duì)象 springAOP 實(shí)現(xiàn) AspectJ 是一個(gè)基于 Java 語(yǔ)言的 AOP 框架,它提供了強(qiáng)大的 AOP 功能,且其實(shí)現(xiàn)方式更為簡(jiǎn)捷,使用更為方便, 而且還支持注解式開發(fā)。所以,Spring 又將 AspectJ 的對(duì)于 AOP 的實(shí)現(xiàn)也引入到了自己的框架中。 首先下載 AOP 相關(guān) jar <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.2.RELEASE</version> </dependency> 1.基于 aspectj 的 xml 配置方式實(shí)現(xiàn) AspectJ 中常用的通知有五種類型: 前置通知,后置通知,環(huán)繞通知,異常通知,最終通知 <bean id="aopdemo" class="com.ff.spring.aop.AopDemo"></bean> <aop:config> <!-- 配置切入點(diǎn) --> <aop:pointcut expression="execution(*com.ff.spring.service.UserService.adduser(..))" id="adduser"/> <aop:pointcut expression="execution(*com.ff.spring.service.UserService.*(..))" id="allmethod"/> <!-- 配置通知和切入點(diǎn) --> <aop:aspect ref="aopdemo"> <aop:before method="savelog" pointcut-ref="adduser"/> <aop:after method="savelog" pointcut-ref="adduser"/> <aop:around method="aroundAdvice" pointcut-ref="adduser"/> <aop:after-throwing method="exceptionAdvice" pointcut-ref="allmethod"?throwing="e" /> </aop:aspect> </aop:config>?
2.基于注解方式的實(shí)現(xiàn) 啟動(dòng) AspectJ 支持:<aop:aspectj-autoproxy /><!--自動(dòng)代理-->?
環(huán)繞通知可以包括前面的所有與通知
Spring 事物管理
概述:??事物可以看做是由對(duì)數(shù)據(jù)庫(kù)若干操作組成的一個(gè)單元。 我們?cè)陂_發(fā)企業(yè)應(yīng)用時(shí),對(duì)于業(yè)務(wù)人員的一個(gè)操作實(shí)際是對(duì)數(shù)據(jù)讀寫的多步操作的結(jié)合。由于數(shù)據(jù)操作在順序執(zhí)行的過(guò)程中,任何一步操作都有可能發(fā)生異常, 異常會(huì)導(dǎo)致后續(xù)操作無(wú)法完成,此時(shí)由于業(yè)務(wù)邏輯并未正確的完成,之前成功操作數(shù)據(jù)的并不可靠,需要在這種情況下進(jìn)行回退。 事務(wù)的作用就是為了保證用戶的每一個(gè)操作都是可靠的,事務(wù)中的每一步操作都必須成功執(zhí)行,只要有發(fā)生異常就回退到事務(wù)開始未進(jìn)行操作的狀態(tài),這些操作要么都完成,要么都取消,從而保證數(shù)據(jù)滿足一致性的要求 Spring 中的事務(wù)管理分為兩種形式,一種是編程式事務(wù),一種是聲明式事務(wù). 編 程 式 事 務(wù) 在 項(xiàng) 目 中 很 少 使 用 , 這 種 方 式 需 要 注 入 一 個(gè) 事 務(wù) 管 理 對(duì) TransactionTemplate ,然后在我們代碼中需要提交事務(wù)或回滾事務(wù)時(shí)自己寫代碼實(shí)現(xiàn). 聲明式事務(wù)管理建立在 AOP 基礎(chǔ)上,本質(zhì)是對(duì)方法前后進(jìn)行攔截,所以聲明式事務(wù)是方法級(jí)別的。 Spring 聲明式事物管理方式有兩種: 基于 xml 配置 基于注解實(shí)現(xiàn) 基于注解實(shí)現(xiàn) 1.配置事物管理器 <!-- 配置 spring 事務(wù)管理類, 并注入數(shù)據(jù)源 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> 2.開啟注解事務(wù)管理? <tx:annotation-driven transaction-manager="transactionManager"/> 3.在 service 中控制事務(wù) @Service(value="adminDao") @Transactional @Transactional的用法? ? ? ? 一般把?? ?@Transactional標(biāo)簽添加在service中,
?? ??? ?@Transactional可以添加在service層中類上,類中所有的方法都會(huì)添加事務(wù)管理功
?? ??? ?@Transactional如果只添加在某個(gè)方法上,那么表示此方法在事務(wù)管理中進(jìn)行
@Transactional在以下6種情況下會(huì)失效.
? ? ? ? ?1.修飾一個(gè)非public的方法,底層權(quán)限只針對(duì)public修飾的方法
? ? ? ? ?2.方法中的異常被catch捕獲處理了
? ? ? ? ?3.默認(rèn)情況下出現(xiàn)編譯期異常,事務(wù)不生效
? ? ? ? ? ? 默認(rèn)情況下只對(duì)運(yùn)行期異常進(jìn)行捕獲@Transactional(rollbackFor = RuntimeException.class)
? ? ? ? ? ? 我們可以把其修改為@Transactional(rollbackFor = Exception.class),這樣就可以處理任意的異常
? ? ? ? ?4.@Transactional事務(wù)傳播行為設(shè)置錯(cuò)誤
? ? ? ? ?5.數(shù)據(jù)庫(kù)引擎不支持事務(wù), 數(shù)據(jù)庫(kù)引擎是mysql底層具體的一種數(shù)據(jù)處理實(shí)現(xiàn)的機(jī)制
? ? ? ? ? ? ?常用的兩個(gè)引擎: innodb(支持事務(wù)功能),myisam(不支持事務(wù))
? ? ? ? ?6.在一個(gè)非事務(wù)方法中使用this(原始的對(duì)象==自己new出來(lái)的對(duì)象)?? ??
Spring 事務(wù)傳播行為
概述: 既然是傳播,那么至少有兩個(gè)東西,才可以發(fā)生傳播。單體不存在傳播這個(gè)行為。 事務(wù)傳播行為(propagation behavior)指的就是當(dāng)一個(gè)事務(wù)方法被另一個(gè)事務(wù)方法調(diào)用時(shí),這個(gè)事務(wù)方法應(yīng)該如何進(jìn)行。事務(wù)傳播行為是 Spring 框架獨(dú)有的事務(wù)增強(qiáng)特性,他不屬于的事務(wù)實(shí)際提供方數(shù)據(jù)庫(kù)行為
Spring 定義了七種傳播行為: PROPAGATION_REQUIRED? ? ? ?如果當(dāng)前沒(méi)有事務(wù),就新建一個(gè)事務(wù),如果已經(jīng)存在一個(gè)事務(wù)中, 加入到這個(gè)事務(wù)中。這是最常見的選擇。 PROPAGATION_SUPPORTS? ? ? ?支持當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方式執(zhí)行。 PROPAGATION_MANDATORY? ? ? 使用當(dāng)前的事務(wù),如果當(dāng)前沒(méi)有事務(wù),就拋出異常。 PROPAGATION_REQUIRES_NEW? ? ? ?新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。 PROPAGATION_NOT_SUPPORTED 以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。 PROPAGATION_NEVER? ? ? ? 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常。 PROPAGATION_NESTED? ? ? ? 如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒(méi)有事務(wù), 則執(zhí)行與 PROPAGATION_REQUIRED 類似的操作。Spring 集成 Mybatis
Spring 集成 Mybatis 其核心是將 SqlSessionFactory 交由 Spring 管理,并由 Spring 管理對(duì) dao 接口的代理實(shí)現(xiàn) 1.導(dǎo)入 mybatis jar 包 Spring 結(jié)合 mybatis 插件包 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> 2.配置 sqlSessionFactory <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="mybatis-config.xml"></property> <property name="mapperLocations" value="com/ff/*Mapper.xml"> </property> </bean> 3.指定生成接口代理 <bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.ff.ssm.dao"></property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"> </property> </bean> 4.在 service 中注入 Dao 代理接口,此接口有 Spring 代理實(shí)現(xiàn) @Resource LoginDao loginDao;總結(jié)
以上是生活随笔為你收集整理的spring超全面详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 猿如意|初识CSDN的开发者工具合集
- 下一篇: 通信协议:CAN总线