Spring整理

Spring

本筆記是在學(xué)習(xí)狂神說java的B站視頻記錄的。

簡介

歷史

2002 —— 雛形interface21框架

作者 —— Rod Johnson,Spring Framework創(chuàng)始人

spring 理念 ——使現(xiàn)有技術(shù)更加容易使用,本身是一個(gè)大雜燴,整合了現(xiàn)有的技術(shù)框架

官網(wǎng)地址:https://spring.io/projects/spring-framework#overview

下載Github:https://github.com/spring-projects/spring-framework

文檔:https://docs.spring.io/spring-framework/docs/5.2.11.RELEASE/spring-framework-reference/core.html#spring-core

優(yōu)點(diǎn)

  • 開源的免費(fèi)的框架(容器)
  • 輕量級(jí)的、非入侵式的框架
  • 控制反轉(zhuǎn)(IOC),面向切面編程(AOP)
  • 支持事務(wù)的處理,對(duì)框架整合的支持

總結(jié)一句話:Spring就是一個(gè)輕量級(jí)的控制反轉(zhuǎn)(IOC)和面向切面編程(AOP)的框架!

組成

spring組成圖

擴(kuò)展

現(xiàn)代化的java開發(fā)就是基于spring的開發(fā)

現(xiàn)代化的java開發(fā)圖
  • Spring Boot
    • 一個(gè)快速開發(fā)的腳手架
    • 基于SpringBoot可以快速的開發(fā)單個(gè)微服務(wù)
    • 約定大于配置
  • SpringCloud
    • SpringCloud是基于SpringBoot實(shí)現(xiàn)的。

弊端

? 發(fā)展了太久之后,違背了原來的理念!配置十分繁瑣,人稱“配置地獄!”

IOC理論推導(dǎo)

  1. UserDao接口
  2. UserDaoImpl實(shí)現(xiàn)類
  3. UserService業(yè)務(wù)接口
  4. UserServiceImpl業(yè)務(wù)實(shí)現(xiàn)接口

之前,程序是主動(dòng)創(chuàng)建對(duì)象

使用set()注入,程序由主動(dòng)變被動(dòng)接收對(duì)象

IOC是一種設(shè)計(jì)思想,依賴注入DI是IOC的一種實(shí)現(xiàn)

IOC解耦圖

HelloSpring

xml里配置<bean class="xxx"></bean>

對(duì)象由spring創(chuàng)建、管理、裝配

new 是走無參構(gòu)造創(chuàng)建對(duì)象

ApplicationContext context = new ClassPathXmlApplication(beans.xml);

context.getBean();

IOC創(chuàng)建對(duì)象方式

1.使用默認(rèn)的無參構(gòu)造

2.假設(shè)要使用有參構(gòu)造創(chuàng)建對(duì)象

  • 下標(biāo)賦值

      <constructor-arg index="0" value="24"></constructor-arg>
      <constructor-arg index="1" value="zhaoyt"></constructor-arg>
    
  • 通過類型

    • 參數(shù)名(name="屬性名")

spring容器相當(dāng)于"婚介所"

Spring配置

別名

<alias name="user" alias="userNew"></alias>

bean的配置

id 唯一標(biāo)識(shí) 相當(dāng)于對(duì)象名

class:bean對(duì)象所對(duì)應(yīng)的全限定名:包名+類名

name:也是別名,同時(shí)可以取多個(gè)

<bean id="user" class="com.zyt.pojo.User" name="user2"></bean>

import

一般用于團(tuán)隊(duì)開發(fā),配置多個(gè)文件,合并為一個(gè)總的。

applicationContext.xml

<import resource="bean1.xml"/>
<import resource="bean2.xml"/>

依賴注入

1.構(gòu)造器注入

2.set方式注入(重點(diǎn))

  • 依賴:bean對(duì)象的創(chuàng)建依賴于容器
  • 注入:bean對(duì)象中的所有屬性,由容器來注入!

3.拓展方式注入

  • p命名空間
 xmlns:p="http://www.springframework.org/schema/p"
<!--p命名空間注入,可以直接注入屬性的值-->
<bean id="user" class="com.zyt.pojo.User" p:name="zyt" p:age="24"/>
  • c命名空間
xmlns:c="http://www.springframework.org/schema/c"
 <!--c命名空間-->
<bean id="user2" class="com.zyt.pojo.User" c:age="18" c:name="zhaoyt"/>

bean作用域

1.單例模式(Spring默認(rèn)機(jī)制)

<bean id="user2" class="com.zyt.pojo.User" c:age="18" c:name="zhaoyt" scope="singleton"/>

2.原型模式:每次從容器中g(shù)et的時(shí)候,都會(huì)產(chǎn)生一個(gè)新的對(duì)象

<bean id="user1" class="com.zyt.pojo.User" p:name="zyt" p:age="24" scope="prototype"/>

3.其余的request、session、application這些只能在web開發(fā)中使用到。

Bean自動(dòng)裝配

  • 自動(dòng)裝配是Spring滿足bean依賴的一種方式
  • Spring會(huì)再上下文中自動(dòng)尋找,并自動(dòng)給bean裝配屬性

在Spring中有三種裝配方式

? 1.在xml中顯示的配置

? 2.在java中顯示的配置

? 3.隱式的自動(dòng)裝配

1.byName

<!--byName:會(huì)自動(dòng)在容器上下文查找,和自己對(duì)象set方法后面對(duì)應(yīng)的值beanid-->
<bean id="people" class="com.zyt.pojo.People" autowire="byName">
    <property name="name" value="zyt" />
</bean>

2.byType

<!--byType:會(huì)自動(dòng)在容器上下文查找,和自己對(duì)象屬性類型相同的bean-->
<bean id="people" class="com.zyt.pojo.People" autowire="byType">
    <property name="name" value="zyt" />
</bean>

小結(jié):

  • byName的時(shí)候,需要保證所有bean的id唯一,并且這個(gè)bean需要和自動(dòng)注入的屬性的set方法的值一致!
  • byType的時(shí)候,需要保證所有bean的class唯一,并且這個(gè)bean需要和自動(dòng)注入的屬性的類型一致!

使用注解實(shí)現(xiàn)自動(dòng)裝配

要使用注解須知:

? 1.導(dǎo)入約束,context約束

? 2.配置注解的支持:<context:annotation-config/>

<beans xmlns="http://www.springframework.org/schema/beans"              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"               xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans        https://www.springframework.org/schema/beans/spring-beans.xsd            http://www.springframework.org/schema/context                       https://www.springframework.org/schema/context/spring-context.xsd">     
    <context:annotation-config/> 
</beans>

@Autowired

直接在屬性上使用即可,也可以set方式上使用!

使用Autowired我們可以不用在寫set方法,前提是你這個(gè)自動(dòng)裝配的屬性在IOC(Spring)容器中存在,且符合名字byName!

@Resource和@Autowired的區(qū)別

  • 都是用來自動(dòng)裝配的,都可以放在屬性字段上
  • @Autowired 通過byType方式實(shí)現(xiàn),而且必須要求這個(gè)對(duì)象存在【常用】
  • @Resource默認(rèn)通過byName的方式實(shí)現(xiàn),如果找不到名字,則通過byType實(shí)現(xiàn)!如果兩個(gè)都找不到的情況下,就報(bào)錯(cuò)!【常用】
  • 執(zhí)行順序不同:@Autowired 通過byType的方式實(shí)現(xiàn)。@Resource默認(rèn)通過byName的方式實(shí)現(xiàn)。

使用注解開發(fā)

spring4之后,要使用注解開發(fā),必須保證aop的包導(dǎo)入了

aop依賴包

使用注解需要導(dǎo)入約束,增加約束的支持

1.bean

2.屬性如何注入

  • @Componet:組件,放在類上,說明這個(gè)類被Spring管理了,就是bean!

    等價(jià)于<bean id="people" class="com.zyt.pojo.People"/>

<context:component-scan base-package="com.zyt.pojo"/>
  • @Value("xxx"):相當(dāng)于 <property name="name" value="zyt"/>

3.衍生的注解

? @Component有幾個(gè)衍生注解,在web開發(fā)中,會(huì)按照mvc三層架構(gòu)分層!

  • dao層【@Repository】

    • service層【@Service】

    • controller層【@Controller】

      這四個(gè)注解功能都是一樣的,都是將某個(gè)類注冊到spring中,bean裝配

4.自動(dòng)裝配

@Nullable //可以使字段為null
@Autowired(required = false)//required屬性用作說明這個(gè)對(duì)象可以為null,否則為空
@Qualifier(value = "cat222")//與Autowired配合使用,指定一個(gè)唯一的bean對(duì)象注入
@Resource(name="dog")//加name指定bean,功能強(qiáng)大一些

5.作用域

@Scope("singleton")

6.小結(jié)

  • xml更加萬能,適用于任何場合!維護(hù)簡單方便
  • 注解 不是自己類使用不了,維護(hù)相對(duì)復(fù)雜!

xml與注解的最佳實(shí)踐

  • xml用來管理bean;

  • 注解只負(fù)責(zé)完成屬性的注入;

  • 必須要讓注解生效,就需要開啟注解支持【重點(diǎn)】

    <!--開啟注解的支持-->
    <context:annotation-config/>
    <!--指定要掃描的包,這個(gè)包下的注解就會(huì)生效-->
    <context:component-scan base-package="com.zyt"/>
    

使用java的方式配置spring

java類替代xml的bean

@Configuration 代表是一個(gè)配置類,相當(dāng)于beans.xml

@Bean,注冊一個(gè)bean,相當(dāng)于bean標(biāo)簽,方法名字相當(dāng)于id屬性,返回類型相當(dāng)于class屬性

@Import也相當(dāng)于import標(biāo)簽

ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

這種純java的配置方式,在springboot中隨處可見

代理模式

為什么要學(xué)習(xí)代理模式?因?yàn)檫@就是SpringAOP的底層!

中介:

代理圖

代理模式分類:

  • 靜態(tài)代理

  • 動(dòng)態(tài)代理

靜態(tài)代理

角色分析:

  • 抽象角色:一般會(huì)使用接口或者抽象類來解決
  • 真實(shí)角色:被代理的角色
  • 代理角色:代理真實(shí)角色,代理后一般會(huì)做一些附屬操作
  • 客戶:訪問代理對(duì)象的人

代理模式的好處

  • 可以使真實(shí)角色的操作更加純粹,不用去關(guān)注一些公共的業(yè)務(wù)。

  • 公共也就交給代理角色,實(shí)現(xiàn)了業(yè)務(wù)的分工。

  • 公共業(yè)務(wù)發(fā)生擴(kuò)展的時(shí)候,方便集中管理

缺點(diǎn)

  • 一個(gè)真實(shí)角色就會(huì)產(chǎn)生一個(gè)代理角色,代碼量會(huì)翻倍,開發(fā)效率變低!

加深印象

AOP機(jī)制圖

動(dòng)態(tài)代理

  • 動(dòng)態(tài)代理和靜態(tài)代理角色一樣

  • 動(dòng)態(tài)代理的代理類是動(dòng)態(tài)生成的,不是我們直接寫好的!

  • 動(dòng)態(tài)代理分為兩大類:基于接口的動(dòng)態(tài)代理,基于類的動(dòng)態(tài)代理

    • 基于接口——JDK動(dòng)態(tài)代理【我們在這里使用】
    • 基于類——cglib
    • java字節(jié)碼——Javassist

需要了解兩個(gè)類:Proxy 代理、InvocationHandler:調(diào)用處理程序

動(dòng)態(tài)代理的好處:

  • 靜態(tài)的好處都有
  • 一個(gè)動(dòng)態(tài)代理類代理的是一個(gè)接口,一般就是對(duì)應(yīng)一類業(yè)務(wù)
  • 一個(gè)動(dòng)態(tài)代理類可以代理多個(gè)類,只要是實(shí)現(xiàn)了同一個(gè)接口即可

AOP

什么是AOP

Aspect Oriented Programming 面向切面編程,通過預(yù)編譯方法和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。

aop技術(shù)

AOP在spring中的作用

提供聲明式事務(wù);允許用戶自定義切面

  • 橫切關(guān)注點(diǎn):跨越應(yīng)用程序多個(gè)模塊的方法或功能
  • 切面(Aspect):類
  • 通知(Advice):類中的方法
  • 目標(biāo)(Target):被通知對(duì)象
  • 代理(Proxy):向目標(biāo)對(duì)象應(yīng)用通知之后創(chuàng)建的對(duì)象
  • 切入點(diǎn)(PointCut):切面通知執(zhí)行的“地點(diǎn)”的定義
  • 連接點(diǎn)(JointPoint):與切入點(diǎn)匹配的執(zhí)行點(diǎn)
自定義切面

SpringAOP中,通過Advice定義橫切邏輯,Spring中支持5種類型的Advice:

前置通知、后置通知、環(huán)繞通知、異常拋出通知、引介通知

通知方式

使用Spring實(shí)現(xiàn)AOP

【重點(diǎn)】使用AOP織入,需要導(dǎo)入一個(gè)依賴包

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.2</version>
    </dependency>

方式一:使用Spring API接口【主要是springAPI接口實(shí)現(xiàn)】

 <aop:config>
        <!--切入點(diǎn):expression表達(dá)式,execution(要執(zhí)行的位置?。?->
        <aop:pointcut id="pointcut" expression="execution(* com.zyt.service.UserServiceImpl.*(..))"/>
        <!--執(zhí)行環(huán)繞增加!-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>

方式二:自定義來實(shí)現(xiàn)AOP【主要是切面定義】

<bean id="diy" class="com.zyt.diy.DiyPointcut"/>
    <aop:config>
        <!--自定義切面,ref要引用的類-->
        <aop:aspect ref="diy">
            <!--切入點(diǎn)-->
            <aop:pointcut id="point" expression="execution(* com.zyt.service.UserServiceImpl.*(..))"/>
            <!--通知-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>

方式三:使用注解實(shí)現(xiàn)!

@Aspect //標(biāo)注這個(gè)類是一個(gè)切面
@Before //前置通知
@After //后置通知
@Around //環(huán)繞通知
//運(yùn)行結(jié)果:
/*   環(huán)繞前
    signaturevoid com.zyt.service.UserService.add()
    ===========方法執(zhí)行前===========
    增加一個(gè)用戶
    環(huán)繞后
    null
    ===========方法執(zhí)行后===========
*/

整合Mybatis

步驟:

  1. 導(dǎo)入相關(guān)jar包
    • junit
    • mybatis
    • mysql數(shù)據(jù)庫
    • spring相關(guān)
    • aop織入
    • mybatis-spring【new】
  2. 編寫配置文件
  3. 測試

回憶mybatis

  1. 編寫實(shí)體類

    User

  2. 編寫核心配置文件

    mybatis-config.xml

  3. 編寫接口

    UserMapper

  4. 編寫xml文件

    UserMapper.xml

  5. 測試

    MyTest

【遇到問題——映射綁定報(bào)錯(cuò)】org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

用maven的build將xml文件加載進(jìn)來

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

Mybatis-Spring

  1. 編寫數(shù)據(jù)源
  2. sqlSessionFactory
  3. sqlSessionTemplate(核心)
  4. 需要給接口加實(shí)現(xiàn)類
  5. 將自己寫的實(shí)現(xiàn)類注入到spring中

聲明式事務(wù)

  1. 回顧事務(wù)
  • 把一組業(yè)務(wù)當(dāng)成一個(gè)業(yè)務(wù)來做;要么都成功,要么都失?。?/li>
  • 事務(wù)在項(xiàng)目開發(fā)中,十分重要,涉及到數(shù)據(jù)的一致性問題,不能馬虎!
  • 確保完整性和一致性

事務(wù)ACID原則

  • 原子性
  • 一致性
  • 隔離性
    • 多個(gè)業(yè)務(wù)可能操作同一個(gè)資源,防止數(shù)據(jù)損壞
  • 持久性
    • 事務(wù)一旦提交,無論系統(tǒng)發(fā)生什么問題,結(jié)果都不會(huì)再被影響,被持久化的寫到存儲(chǔ)器中!

2.spring中的事務(wù)

  • 聲明式事務(wù):AOP
  • 編程式事務(wù),需要在代碼中,進(jìn)行事務(wù)的管理

思考:

為什么需要事務(wù)?

  • 如果不配置事務(wù),可能存在數(shù)據(jù)提交不一致的情況下;
  • 如果我們不在spring去配置聲明式事務(wù),我們就需要在代碼中手動(dòng)配置事務(wù)!
  • 事務(wù)在項(xiàng)目的開發(fā)中十分重要,設(shè)計(jì)到數(shù)據(jù)的一致性和完整性問題,不容馬虎!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容