山東網(wǎng)站建設(shè)最便宜如何讓百度能查到自己
Spring
Spring 是什么?
Spring 是于 2003 年興起的一個(gè)輕量級(jí)的,IOC 和 AOP 的 Java 開(kāi)發(fā)框架,它 是為了簡(jiǎn)化企業(yè)級(jí)應(yīng)用開(kāi)發(fā)而生的。
Spring有幾大特點(diǎn)如下
輕量級(jí)的
Spring 框架使用的 jar 都比較小,一般在 1M 以下或者幾百 kb。Spring 核 心功能的所需的 jar 總共在 3M 左右。 Spring 框架運(yùn)行占用的資源少,運(yùn)行 效率高。
IOC
控制反轉(zhuǎn),即 Inversion of Control,縮寫(xiě)為 IOC,就是由 Spring IoC 容器管理對(duì)象,而 非傳統(tǒng)實(shí)現(xiàn)中由程序代碼直接操控.
AOP
直譯過(guò)來(lái)就是 面向切面編程。AOP 是一種編程思想,是面向?qū)ο缶幊?#xff08;OOP) 的一種補(bǔ)充。面向?qū)ο缶幊虒⒊绦虺橄蟪筛鱾€(gè)層次的對(duì)象,而面向切面編程是將 程序抽象成各個(gè)切面.
一站式框架
Spring 本身也提供了數(shù)據(jù)訪問(wèn)功能和 web 功能,以及可以很好的管理其他框架.
提供核心功能,主要是IOC,創(chuàng)建管理對(duì)象.
?? ? ?提供面向切面編程,增強(qiáng)程序擴(kuò)展
?? ? ?對(duì)數(shù)據(jù)訪問(wèn)層進(jìn)行了封裝(重點(diǎn)在于事務(wù)管理)
?? ? ?對(duì)web層進(jìn)行封裝,使得請(qǐng)求更加便捷
Spring 體系結(jié)構(gòu)
Core Container(核心容器):
? ? ? ? Beans: 管理 Beans
? ? ? ? Core: Spring 核心
? ? ? ? Context: 配置文件
? ? ? ? ExpressionLanguage: SpEL 表達(dá)式?
AOP(切面編程)
AOP 框架: Aspects
Data Access(數(shù)據(jù)庫(kù)整合):? ?JDBC, ORM, OXM, JMS, Transaction
Web(MVC Web 開(kāi)發(fā)):? ? Web, Servlet, Portlet, Struts
Test(Junit 整合)
官網(wǎng)地址: https://spring.io/
Spring? 搭建
Maven 導(dǎo)入 spring 核心基礎(chǔ) jar
<!-- spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
編寫(xiě) 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="user" class="com.ff.spring.bean.User"> </bean>
</beans>
編寫(xiě)一個(gè) User 實(shí)體類(lèi)
測(cè)試 spring
IOC(控制反轉(zhuǎn))
讀作“反轉(zhuǎn)控制”(Inverse of Control)更好理解,不是什么技術(shù),而是一種 設(shè)計(jì)思想,就是將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán),交由 Spring 框架來(lái) 管理。
IOC 容器是具有依賴注入功能的容器,負(fù)責(zé)對(duì)象的實(shí)例化、對(duì)象的初始化,對(duì) 象和對(duì)象之間依賴關(guān)系配置、對(duì)象的銷(xiāo)毀、對(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 管理
基于 xml 配置方式
bean 配置需要 spring 管理的類(lèi)
id 生成的對(duì)象名
class 全類(lèi)名
name 對(duì)象別名,可以為多個(gè)
scope:
? ? ? singleton(默認(rèn)值):在 Spring 中只存在一個(gè) bean 實(shí)例, 單例模式.
? ? ? prototype:原型 getBean()的時(shí)候都會(huì) new Bean()
? ? ? request:每次 http 請(qǐng)求都會(huì)創(chuàng)建一個(gè) bean, 僅用于 WebApplicationContext 環(huán)境
session:同一個(gè) http session 共享一個(gè) Bean, 不同 Session 使用不同的 Bean, 使用環(huán)境同上
Xml 配置方式依賴注入?
指 Spring 創(chuàng)建對(duì)象的過(guò)程中,將對(duì)象依賴屬性(簡(jiǎn)單值,集合,對(duì)象)通 過(guò)配置設(shè)置給該對(duì)象。
實(shí)現(xiàn) IOC 需要 DI 做支持
注入的方式:
? ? ? ?set 方法注入
? ? ? ?構(gòu)造方法注入
注解方式實(shí)現(xiàn)
注解開(kāi)發(fā)準(zhǔn)備工作
注解需要的 jar 包
注解功能封裝在 AOP 包中,導(dǎo)入 Spring aop jar 包即可
開(kāi)啟注解掃描
<context:component-scan base-package="包名"> </context:component-scan>
注解創(chuàng)建對(duì)象
@Component(value=“user”)等于
<bean id=“user” class=“”></bean>
@Service
@Repository
以上注解都可以實(shí)現(xiàn)創(chuàng)建對(duì)象功能,只是為了后續(xù)擴(kuò)展功能,在不同的層 使用不同的注解標(biāo)記
@Scope(value=“prototype”) 原型
@Scope(value=“ singleton ”) 單例
注解方式注入屬性
@Autowired
@Autowired 是 Spring 提供的注解,可以寫(xiě)在字段和 setter 方法上。如果寫(xiě)在 字段上,那么就不需要再寫(xiě) setter 方法。默認(rèn)情況下它要求依賴對(duì)象必須存在, 如果允許 null 值,可以設(shè)置它的 required 屬性為 false。
byType 自動(dòng)注入
該注解默認(rèn)使用按類(lèi)型自動(dòng)裝配 Bean 的方式。
byName 自動(dòng)注入
如果我們想使用按照名稱(chēng)(byName)來(lái)裝配,可以結(jié)合@Qualifier 注解一起 使用
需要在引用屬性上聯(lián)合使用注解@Autowired 與@Qualifier。@Qualifier 的 value 屬性用于指定要匹配的 Bean 的 id 值。
JDK 注解@Resource 自動(dòng)注入
Spring 提供了對(duì) jdk 中@Resource 注解的支持。@Resource 注解既可以按名 稱(chēng)匹配 Bean,也可以按類(lèi)型匹配 Bean。默認(rèn)按照 ByName 自動(dòng)注入
byName 注入引用類(lèi)型屬性
@Resource 注解指定其 name 屬性,則 name 的值即為按照名稱(chēng)進(jìn)行匹配 的 Bean 的 id。
注解與 XML 的對(duì)比
注解優(yōu)點(diǎn): 方便,直觀,高效(代碼少,沒(méi)有配置文件的書(shū)寫(xiě)那么復(fù)雜)。
注解缺點(diǎn):以硬編碼的方式寫(xiě)入到 Java 代碼中,修改是需要重新編譯代碼的。
xml 優(yōu)點(diǎn)是: 配置和代碼是分離的,在 xml 中做修改,無(wú)需編譯代碼,只需重 啟服務(wù)器即可將新的配置加載。
xml 的缺點(diǎn)是:編寫(xiě)麻煩,效率低,大型項(xiàng)目過(guò)于復(fù)雜。
Spring JDBC
Spring 是個(gè)一站式框架:Spring 自身也提供了控制層的 SpringMVC 和 持久 層的 Spring JdbcTemplate。
開(kāi)發(fā)步驟
下載 Spring JdbcTemplate 的 jar 包
<!-- spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- 阿里數(shù)據(jù)源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
導(dǎo)入屬性文件
<context:property-placeholder location="config.properties"/>
管理數(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>
在配置文件中創(chuàng)建 JdbcTemplate
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
在類(lèi)中獲得 JdbcTemplate 對(duì)象,就可以直接使用。
JdbcTemplate 中常用的方法?
execute:無(wú)返回值,可執(zhí)行 ddl,增刪改語(yǔ)句
update:執(zhí)行新增、修改、刪除語(yǔ)句;
queryForXXX:執(zhí)行查詢相關(guān)語(yǔ)句;
不使用 AOP 的開(kāi)發(fā)方式
先定義好接口與一個(gè)實(shí)現(xiàn)類(lèi),該實(shí)現(xiàn)類(lèi)中除了要實(shí)現(xiàn)接口中的方法外,還要 再寫(xiě)兩個(gè)非業(yè)務(wù)方法。非業(yè)務(wù)方法也稱(chēng)為交叉業(yè)務(wù)邏輯:
? doTransaction():用于事務(wù)處理
? doLog():用于日志處理
然后,再使接口方法調(diào)用它們。接口方法也稱(chēng)為主業(yè)務(wù)邏輯.
AOP 概述
AOP 為 Aspect Oriented Programming 的縮寫(xiě),意為:面向切面編程,通過(guò) 預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。
AOP 是 OOP 的延續(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),是 java 開(kāi)發(fā)中的一個(gè)重要內(nèi) 容。利用 AOP 可以對(duì)業(yè)務(wù)邏輯和非業(yè)務(wù)邏輯進(jìn)行隔離,從而使得各部分之間的 耦合度降低,提高程序的可重用性,同時(shí)提高了開(kāi)發(fā)的效率。
AOP、OOP 在字面上雖然非常類(lèi)似,但卻是面向不同領(lǐng)域的兩種設(shè)計(jì)思想。OOP (面向?qū)ο缶幊?#xff09;針對(duì)業(yè)務(wù)處理過(guò)程的實(shí)體及其屬性和行為進(jìn)行抽象封裝,以獲 得更加清晰高效的邏輯單元?jiǎng)澐帧?/p>
而 AOP 則是針對(duì)業(yè)務(wù)處理過(guò)程中的切面進(jìn)行提取,它所面對(duì)的是處理過(guò)程中的 某個(gè)步驟或階段,以獲得邏輯過(guò)程中各部分之間低耦合性的隔離效果。這兩種設(shè) 計(jì)思想在目標(biāo)上有著本質(zhì)的差異。
面向切面編程的好處就是: 減少重復(fù),專(zhuān)注業(yè)務(wù);
注意:面向切面編程只是面向?qū)ο缶幊痰囊环N補(bǔ)充。
核心原理:
使用動(dòng)態(tài)代理的方式在執(zhí)行方法前后或者出現(xiàn)異常的時(shí)候做加入相關(guān)的邏輯
使用案例:
事務(wù)處理:開(kāi)啟事務(wù),關(guān)閉事務(wù),出現(xiàn)異常后回滾事務(wù)
權(quán)限判斷:在執(zhí)行方法前,判斷是否具有權(quán)限
日志:在執(zhí)行前進(jìn)行日志處理
AOP 的基本概念
連接點(diǎn)(Joinpoint):類(lèi)中可以被增強(qiáng)的方法,這個(gè)方法就被稱(chēng)為連接點(diǎn)
切入點(diǎn)(pointcut):類(lèi)中有很多方法可以被增強(qiáng),但實(shí)際中只有 add 和 update 被增了,那么 add 和 update 方法就被稱(chēng)為切入點(diǎn)(實(shí)際實(shí)現(xiàn)的連接點(diǎn))
通知(Advice): 通知是指一個(gè)切面在特定的連接點(diǎn)要做的事情(增強(qiáng)的功能)。通 知分為方法執(zhí)行前通知,方法執(zhí)行后通知,環(huán)繞通知等.
切面(Aspect):把通知添加到切入點(diǎn)的整個(gè)過(guò)程稱(chēng)為切面.
目標(biāo)(Target): 代理的目標(biāo)對(duì)象(連接點(diǎn),切入點(diǎn)所在類(lèi))
代理(Proxy): 向目標(biāo)對(duì)象應(yīng)用通知時(shí)創(chuàng)建的代理對(duì)象
springAOP 實(shí)現(xiàn)
對(duì)于 AOP 這種編程思想,很多框架都進(jìn)行了實(shí)現(xiàn)。Spring 就是其中之一,可 以完成面向切面編程。
AspectJ 是一個(gè)基于 Java 語(yǔ)言的 AOP 框架,它提供了強(qiáng)大的 AOP 功能,且其實(shí) 現(xiàn)方式更為簡(jiǎn)捷,使用更為方便, 而且還支持注解式開(kāi)發(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>
基于 aspectj 的 xml 配置方式實(shí)現(xià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>
AspectJ 中常用的通知有五種類(lèi)型:
前置通知 before 業(yè)務(wù)方法執(zhí)行前調(diào)用 后置通知 after-returning 業(yè)務(wù)方法執(zhí)行后執(zhí)行,當(dāng)方法出現(xiàn)異常不執(zhí)行 異常通知 after-throwing 業(yè)務(wù)方法出現(xiàn)異常時(shí)調(diào)用 最終通知 after 業(yè)務(wù)方法執(zhí)行后調(diào)用 當(dāng)方法出現(xiàn)異常也會(huì)執(zhí)行 環(huán)繞通知 around
?
基于注解方式的實(shí)現(xiàn)
啟動(dòng) AspectJ 支持:
<aop:aspectj-autoproxy />
@Component
@Aspect
public class AOPDemo {
@Before("execution(* com.ff.spring.demo1.dao.UserDao.*(..))")
public void before(){
System.out.println("before");
}
@After("execution(* com.ff.spring.demo1.dao.UserDao.*(..))")
public void after(){
System.out.println("after");
}
@Around("execution(* com.ff.spring.demo1.dao.UserDao.*(..))")
public void around(ProceedingJoinPoint point) throws Throwable {
System.out.println("start");
point.proceed();
System.out.println("end");
}
@AfterThrowing(value = "execution(* com.ff.spring.demo1.dao.UserDao.*(..))",throwing = "e")
public void afterthrow(Throwable){
System.out.println("afterthrow");
}
@AfterReturning("execution(* com.ff.spring.demo1.dao.UserDao.*(..))")
public void afterreturn(){
System.out.println("afterreturn");
}
}
Spring 事物管理
事物可以看做是由對(duì)數(shù)據(jù)庫(kù)若干操作組成的一個(gè)單元。
我們?cè)陂_(kāi)發(fā)企業(yè)應(yīng)用時(shí),對(duì)于業(yè)務(wù)人員的一個(gè)操作實(shí)際是對(duì)數(shù)據(jù)讀寫(xiě)的多步操作 的結(jié)合。由于數(shù)據(jù)操作在順序執(zhí)行的過(guò)程中,任何一步操作都有可能發(fā)生異常, 異常會(huì)導(dǎo)致后續(xù)操作無(wú)法完成,此時(shí)由于業(yè)務(wù)邏輯并未正確的完成,之前成功操 作數(shù)據(jù)的并不可靠,需要在這種情況下進(jìn)行回退。
事務(wù)的作用就是為了保證用戶的每一個(gè)操作都是可靠的,事務(wù)中的每一步操作都 必須成功執(zhí)行,只要有發(fā)生異常就回退到事務(wù)開(kāi)始未進(jìn)行操作的狀態(tài),這些操作 要么都完成,要么都取消,從而保證數(shù)據(jù)滿足一致性的要求
Spring 中的事務(wù)管理分為兩種形式,一種是編程式事務(wù),一種是聲明式事務(wù)。
編 程 式 事 務(wù) 在 項(xiàng) 目 中 很 少 使 用 , 這 種 方 式 需 要 注 入 一 個(gè) 事 務(wù) 管 理 對(duì) 象 TransactionTemplate ,然后在我們代碼中需要提交事務(wù)或回滾事務(wù)時(shí)自己寫(xiě)代 碼實(shí)現(xiàn)。
聲 明 式 事 務(wù)管理建立在 AOP 基礎(chǔ)上,本質(zhì)是對(duì)方法前后進(jìn)行攔截,所以聲明式 事務(wù)是方法級(jí)別的。
Spring 聲明式事物管理方式有兩種:? ? 基于 xml 配置? ? ? ? ? 基于注解實(shí)現(xiàn)
Spring 針對(duì)不同的 dao 框架,提供了不同的實(shí)現(xiàn)類(lèi),Jdbc,mybatis 事物管理實(shí) 現(xiàn)類(lèi)是 DataSourceTransactionManager
配置事物管理器
<!-- 配置 spring 事務(wù)管理類(lèi), 并注入數(shù)據(jù)源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
注解方式
<!-- 開(kāi)啟注解事務(wù)管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
在 service 中控制事務(wù)? ? ?@Service(value="userservice")? ? ? ?@Transactiona
聲明式事務(wù)不生效的場(chǎng)景
@Transactional 應(yīng)用在非 public 修飾的方法上 異常被 catch 捕獲導(dǎo)致失效 出現(xiàn)編譯期異常
@Transactional 事務(wù)傳播行為設(shè)置錯(cuò)誤 數(shù)據(jù)庫(kù)引擎不支持事務(wù) 同一個(gè)類(lèi)中,使用非代理對(duì)象調(diào)用一個(gè)有事務(wù)的方法,導(dǎo)致事務(wù)錯(cuò)誤
Spring 事務(wù)傳播行為
什么叫事務(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ù)行為.
例如:methodA 事務(wù)方法調(diào)用 methodB 事務(wù)方法時(shí),methodB 是繼續(xù)在調(diào) 用者 methodA 的事務(wù)中運(yùn)行呢,還是為自己開(kāi)啟一個(gè)新事務(wù)運(yùn)行,這就是由 methodB 的事務(wù)傳播行為決定的。
Spring 定義了七種傳播行為:
?
Spring 集成 Mybatis
Spring 集成 Mybatis 其核心是將 SqlSessionFactory 交由 Spring 管理,并由 Spring 管理對(duì) dao 接口的代理實(shí)現(xiàn)。
導(dǎo)入 mybatis jar 包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
配置 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>
指定生成接口代理
<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>
在 service 中注入 Dao 代理接口,此接口有 Spring 代理實(shí)現(xiàn)
?