亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

初學(xué)者,Spring快速入門

 更新時(shí)間:2021年09月03日 16:53:47   作者:王延領(lǐng)  
本文主要講解了Spring框架的基礎(chǔ)知識(shí),Spring是一個(gè)輕量級(jí)的開源框架,它是為簡(jiǎn)化企業(yè)級(jí)應(yīng)用開發(fā)而生。文中運(yùn)用代碼非常詳細(xì)的介紹了相關(guān)知識(shí),需要了解的小伙伴可以參考一下哦

1.spring

Spring 框架可以說是Java 世界最為成功的框架,在企業(yè)實(shí)際應(yīng)用中,大部分的企業(yè)架構(gòu)都基于Spring 框架。它的成功來自于理念,而不是技術(shù),它最為核心的理念是IoC (控制反轉(zhuǎn))和AOP (面向切面編程),其中IoC 是Spring的基礎(chǔ),而AOP 則是其重要的功能,最為典型的當(dāng)屬數(shù)據(jù)庫(kù)事務(wù)的使用。

Spring最根本的使命是解決企業(yè)級(jí)應(yīng)用開發(fā)的復(fù)雜性,即簡(jiǎn)化Java開發(fā)。

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

1.方便解耦,簡(jiǎn)化開發(fā)

Spring就是一個(gè)大工廠,可以將所有對(duì)象的創(chuàng)建和依賴關(guān)系的維護(hù),交給Spring管理。

2.AOP編程的支持

Spring提供面向切面編程,可以方便的實(shí)現(xiàn)對(duì)程序進(jìn)行權(quán)限攔截、運(yùn)行監(jiān)控等功能。

3.聲明式事務(wù)的支持

只需要通過配置就可以完成對(duì)事務(wù)的管理,而無需手動(dòng)編程。

4.方便程序的測(cè)試

Spring對(duì)Junit4支持,可以通過注解方便的測(cè)試Spring程序。

5.方便集成各種優(yōu)秀框架

Spring不排斥各種優(yōu)秀的開源框架,其內(nèi)部提供了對(duì)各種優(yōu)秀框架的直接支持(如:Struts、Hibernate、MyBatis等)。

6.降低JavaEE API的使用難度

Spring對(duì)JavaEE開發(fā)中非常難用的一些API(JDBC、JavaMail、遠(yuǎn)程調(diào)用等),都提供了封裝,使這些API應(yīng)用難度大大降低。

1.2.缺點(diǎn)

1.Spring明明一個(gè)很輕量級(jí)的框架,卻給人感覺大而全

2.Spring依賴反射,反射影響性能

3.使用門檻升高,入門Spring需要較長(zhǎng)時(shí)間

1.3.Spring框架的組成結(jié)構(gòu)圖

Spring 總共大約有 20 個(gè)模塊, 由 1300 多個(gè)不同的文件構(gòu)成。 而這些組件被分別整合在核心容器(Core Container) 、 AOP(Aspect Oriented Programming)和設(shè)備支持(Instrmentation) 、數(shù)據(jù)訪問與集成(Data Access/Integeration) 、 Web、 消息(Messaging) 、 Test等 6 個(gè)模塊中。 以下是 Spring 5 的模塊結(jié)構(gòu)圖:

組成 Spring 框架的每個(gè)模塊(或組件)都可以單獨(dú)存在,或者與其他一個(gè)或多個(gè)模塊聯(lián)合實(shí)現(xiàn)。每個(gè)模塊的功能如下:

1.3.1.核心容器

Spring的核心容器是其他模塊建立的基礎(chǔ),有spring-core、spring-beans、spring-context、spring-context-support和spring-expression(Spring表達(dá)式語(yǔ)言)等模塊組成。

spring-core 模塊:提供了框架的基本組成部分,包括控制反轉(zhuǎn)(Inversion of Control,IOC)和依賴注入(Dependency Injection,DI)功能。

spring-beans 模塊:提供了BeanFactory,是工廠模式的一個(gè)經(jīng)典實(shí)現(xiàn),Spring將管理對(duì)象稱為Bean。

spring-context 模塊:建立在Core和Beans模塊的基礎(chǔ)之上,提供一個(gè)框架式的對(duì)象訪問方式,是訪問定義和配置的任何對(duì)象的媒介。ApplicationContext接口是Context模塊的焦點(diǎn)。

spring-context-support 模塊:支持整合第三方庫(kù)到Spring應(yīng)用程序上下文,特別是用于高速緩存(EhCache、JCache)和任務(wù)調(diào)度(CommonJ、Quartz)的支持。

Spring-expression 模塊:提供了強(qiáng)大的表達(dá)式語(yǔ)言去支持運(yùn)行時(shí)查詢和操作對(duì)象圖。這是對(duì)JSP2.1規(guī)范中規(guī)定的統(tǒng)一表達(dá)式語(yǔ)言(Unified EL)的擴(kuò)展。該語(yǔ)言支持設(shè)置和獲取屬性值、屬性分配、方法調(diào)用、訪問數(shù)組、集合和索引器的內(nèi)容、邏輯和算術(shù)運(yùn)算、變量命名以及從Spring的IOC容器中以名稱檢索對(duì)象。它還支持列表投影、選擇以及常用的列表聚合。

1.3.2.AOP 和設(shè)備支持

由spring-aop、 spring-aspects 和 spring-instrument等 3 個(gè)模塊組成。

spring-aop 模塊:是 Spring 的另一個(gè)核心模塊,提供了一個(gè)符合 AOP 要求的面向切面的編程實(shí)現(xiàn)。 作為繼 OOP(面向?qū)ο缶幊蹋?后, 對(duì)程序員影響最大的編程思想之一, AOP 極大地開拓了人們對(duì)于編程的思路。 在 Spring 中, 以動(dòng)態(tài)代理技術(shù)為基礎(chǔ),允許定義方法攔截器和切入點(diǎn),將代碼按照功能進(jìn)行分離,以便干凈地解耦。

spring-aspects 模塊:提供了與AspectJ的集成功能,AspectJ是一個(gè)功能強(qiáng)大且成熟的AOP框架。

spring-instrument 模塊:是 AOP 的一個(gè)支援模塊, 提供了類植入(Instrumentation)支持和類加載器的實(shí)現(xiàn),可以在特定的應(yīng)用服務(wù)器中使用。主要作用是在 JVM 啟用時(shí), 生成一個(gè)代理類, 程序員通過代理類在運(yùn)行時(shí)修改類的字節(jié), 從而改變一個(gè)類的功能, 實(shí)現(xiàn) AOP 的功能。

1.3.3.數(shù)據(jù)訪問與集成

由 spring-jdbc、spring-orm、spring-oxm、spring-jms 和 spring-tx 等 5 個(gè)模塊組成。

spring-jdbc 模塊:提供了一個(gè)JDBC的抽象層,消除了煩瑣的JDBC編碼和數(shù)據(jù)庫(kù)廠商特有的錯(cuò)誤代碼解析, 用于簡(jiǎn)化JDBC。主要是提供 JDBC 模板方式、 關(guān)系數(shù)據(jù)庫(kù)對(duì)象化方式、 SimpleJdbc 方式、 事務(wù)管理來簡(jiǎn)化 JDBC 編程, 主要實(shí)現(xiàn)類是 JdbcTemplate、 SimpleJdbcTemplate 以及 NamedParameterJdbcTemplate。

spring-orm 模塊:是 ORM 框架支持模塊, 主要集成 Hibernate, Java Persistence API (JPA) 和Java Data Objects (JDO) 用于資源管理、 數(shù)據(jù)訪問對(duì)象(DAO)的實(shí)現(xiàn)和事務(wù)策略。

spring-oxm 模塊:主要提供一個(gè)抽象層以支撐 OXM(OXM 是 Object-to-XML-Mapping 的縮寫, 它是一個(gè) O/M-mapper, 將 java 對(duì)象映射成 XML 數(shù)據(jù), 或者將 XML 數(shù)據(jù)映射成 java 對(duì)象) , 例如: JAXB,Castor,XMLBeans,JiBX 和 XStream 等。

spring-jms模塊(Java Messaging Service):指Java消息傳遞服務(wù),包含用于生產(chǎn)和使用消息的功能。自Spring4.1以后,提供了與spring-messaging模塊的集成。

spring-tx 模塊:事務(wù)模塊,支持用于實(shí)現(xiàn)特殊接口和所有POJO(普通Java對(duì)象)類的編程和聲明式事務(wù)管理。

1.3.4.Web

由spring-websocket、spring-webmvc、spring-web、portlet和spring-webflux模塊等 5 個(gè)模塊組成。

spring-websocket 模塊:Spring4.0以后新增的模塊,實(shí)現(xiàn)雙工異步通訊協(xié)議,實(shí)現(xiàn)了WebSocket和SocketJS,提供Socket通信和web端的推送功能。

spring-webmvc 模塊:也稱為Web-Servlet模塊,包含用于web應(yīng)用程序的Spring MVC和REST Web Services實(shí)現(xiàn)。Spring MVC框架提供了領(lǐng)域模型代碼和Web表單之間的清晰分離,并與Spring Framework的所有其他功能集成。

spring-web 模塊:提供了基本的Web開發(fā)集成功能,包括使用Servlet監(jiān)聽器初始化一個(gè)IOC容器以及Web應(yīng)用上下文,自動(dòng)載入WebApplicationContext特性的類,Struts集成類、文件上傳的支持類、Filter類和大量輔助工具類。

portlet 模塊:實(shí)現(xiàn)web模塊功能的聚合,類似于Servlet模塊的功能,提供了Portlet環(huán)境下的MVC實(shí)現(xiàn)。

spring-webflux 模塊:是一個(gè)新的非堵塞函數(shù)式 Reactive Web 框架, 可以用來建立異步的, 非阻塞,事件驅(qū)動(dòng)的服務(wù), 并且擴(kuò)展性非常好。

1.3.5.消息(Messaging)

即 spring-messaging 模塊。

spring-messaging 是從 Spring4 開始新加入的一個(gè)模塊, 該模塊提供了對(duì)消息傳遞體系結(jié)構(gòu)和協(xié)議的支持。

1.3.6.Test

即 spring-test 模塊。

spring-test 模塊主要為測(cè)試提供支持的,支持使用JUnit或TestNG對(duì)Spring組件進(jìn)行單元測(cè)試和集成測(cè)試。

2.Spring核心ioc

Ioc—Inversion of Control,即“控制反轉(zhuǎn)”,不是什么技術(shù),而是一種設(shè)計(jì)思想。在Java開發(fā)中,Ioc意味著將你設(shè)計(jì)好的對(duì)象交給容器控制,而不是傳統(tǒng)的在你的對(duì)象內(nèi)部直接控制。就是不實(shí)例化了。先注入。

誰(shuí)控制誰(shuí),控制什么:傳統(tǒng)Java SE程序設(shè)計(jì),我們直接在對(duì)象內(nèi)部通過new進(jìn)行創(chuàng)建對(duì)象,是程序主動(dòng)去創(chuàng)建依賴對(duì)象;而IoC是有專門一個(gè)容器來創(chuàng)建這些對(duì)象,即由Ioc容器來控制對(duì)象的創(chuàng)建;誰(shuí)控制誰(shuí)?當(dāng)然是IoC 容器控制了對(duì)象;控制什么?那就是主要控制了外部資源獲取。

為何是反轉(zhuǎn),哪些方面反轉(zhuǎn)了:有反轉(zhuǎn)就有正轉(zhuǎn),傳統(tǒng)應(yīng)用程序是由我們自己在對(duì)象中主動(dòng)控制去直接獲取依賴對(duì)象,也就是正轉(zhuǎn);而反轉(zhuǎn)則是由容器來幫忙創(chuàng)建及注入依賴對(duì)象;為何是反轉(zhuǎn)?因?yàn)橛扇萜鲙臀覀儾檎壹白⑷胍蕾噷?duì)象,對(duì)象只是被動(dòng)的接受依賴對(duì)象,所以是反轉(zhuǎn);哪些方面反轉(zhuǎn)了?依賴對(duì)象的獲取被反轉(zhuǎn)了。

ps:控制反轉(zhuǎn)是目標(biāo),依賴注入是手段。

2.1.ioc容器

IoC 容器是 Spring 的核心,也可以稱為 Spring 容器。Spring 通過 IoC 容器來管理對(duì)象的實(shí)例化和初始化,以及對(duì)象從創(chuàng)建到銷毀的整個(gè)生命周期。

Spring 中使用的對(duì)象都由 IoC 容器管理,不需要我們手動(dòng)使用 new 運(yùn)算符創(chuàng)建對(duì)象。由 IoC 容器管理的對(duì)象稱為 Spring Bean,Spring Bean 就是 Java 對(duì)象,和使用 new 運(yùn)算符創(chuàng)建的對(duì)象沒有區(qū)別。

Spring 通過讀取 XML 或 Java 注解中的信息來獲取哪些對(duì)象需要實(shí)例化。

Spring 提供 2 種不同類型的 IoC 容器,即 BeanFactory 和 ApplicationContext 容器

2.1.1.BeanFactory 容器

BeanFactory 是最簡(jiǎn)單的容器,由 org.springframework.beans.factory.BeanFactory 接口定義,采用懶加載(lazy-load),所以容器啟動(dòng)比較快。BeanFactory 提供了容器最基本的功能。

為了能夠兼容 Spring 集成的第三方框架(如 BeanFactoryAware、InitializingBean、DisposableBean),所以目前仍然保留了該接口。

簡(jiǎn)單來說,BeanFactory 就是一個(gè)管理 Bean 的工廠,它主要負(fù)責(zé)初始化各種 Bean,并調(diào)用它們的生命周期方法。

BeanFactory 接口有多個(gè)實(shí)現(xiàn)類,最常見的是 org.springframework.beans.factory.xml.XmlBeanFactory。使用 BeanFactory 需要?jiǎng)?chuàng)建 XmlBeanFactory 類的實(shí)例,通過 XmlBeanFactory 類的構(gòu)造函數(shù)來傳遞 Resource 對(duì)象。如下所示。

Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);  

2.1.2. ApplicationContext 容器

ApplicationContext 繼承了 BeanFactory 接口,由 org.springframework.context.ApplicationContext 接口定義,對(duì)象在啟動(dòng)容器時(shí)加載。ApplicationContext 在 BeanFactory 的基礎(chǔ)上增加了很多企業(yè)級(jí)功能,例如 AOP、國(guó)際化、事件支持等。

ApplicationContext 接口有兩個(gè)常用的實(shí)現(xiàn)類,具體如下。

2.1.2.1.ClassPathXmlApplicationContext

該類從類路徑 ClassPath 中尋找指定的 XML 配置文件,并完成 ApplicationContext 的實(shí)例化工作,具體如下所示。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation)

在上述代碼中,configLocation 參數(shù)用于指定 Spring 配置文件的名稱和位置,如 Beans.xml。

2.1.2.2.FileSystemXmlApplicationContext

該類從指定的文件系統(tǒng)路徑中尋找指定的 XML 配置文件,并完成 ApplicationContext 的實(shí)例化工作,具體如下所示。

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

它與 ClassPathXmlApplicationContext 的區(qū)別是:在讀取 Spring 的配置文件時(shí),F(xiàn)ileSystemXmlApplicationContext 不會(huì)從類路徑中讀取配置文件,而是通過參數(shù)指定配置文件的位置。即 FileSystemXmlApplicationContext 可以獲取類路徑之外的資源,如“F:/workspaces/Beans.xml”。

2.1.2.3.AnnotationConfigApplicationContext

讀取用注解創(chuàng)建容器

通常在 Java 項(xiàng)目中,會(huì)采用 ClassPathXmlApplicationContext 類實(shí)例化 ApplicationContext 容器的方式,而在 Web 項(xiàng)目中,ApplicationContext 容器的實(shí)例化工作會(huì)交由 Web 服務(wù)器完成。Web 服務(wù)器實(shí)例化 ApplicationContext 容器通常使用基于 ContextLoaderListener 實(shí)現(xiàn)的方式,它只需要在 web.xml 中添加如下代碼:

<!--指定Spring配置文件的位置,有多個(gè)配置文件時(shí),以逗號(hào)分隔-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!--spring將加載spring目錄下的applicationContext.xml文件-->
    <param-value>
        classpath:spring/applicationContext.xml
    </param-value>
</context-param>
<!--指定以ContextLoaderListener方式啟動(dòng)Spring容器-->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

要注意的是,BeanFactory 和 ApplicationContext 都是通過 XML 配置文件加載 Bean 的。

二者的主要區(qū)別在于,如果 Bean 的某一個(gè)屬性沒有注入,使用 BeanFacotry 加載后,第一次調(diào)用 getBean() 方法時(shí)會(huì)拋出異常,而 ApplicationContext 則會(huì)在初始化時(shí)自檢,這樣有利于檢查所依賴的屬性是否注入。

因此,在實(shí)際開發(fā)中,通常都選擇使用 ApplicationContext,只有在系統(tǒng)資源較少時(shí),才考慮使用 BeanFactory。

2.2.使用ioc容器

2.2.1.beans.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">
    <bean id="user" class="com.wyl.pojo.User">
        <property name="name" value="王延領(lǐng)"/>
    </bean>
</beans>

2.2.2.pojo.User

public class User { 
    private String name; 
    public User() {
        System.out.println("user無參構(gòu)造方法");
    } 
    public void setName(String name) {
        this.name = name;
    } 
    public void show(){
        System.out.println("name="+ name );
    }
}

2.2.3.test

@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    //在執(zhí)行g(shù)etBean的時(shí)候, user已經(jīng)創(chuàng)建好了 , 通過無參構(gòu)造
    User user = (User) context.getBean("user");
    //調(diào)用對(duì)象的方法 .
    user.show();
}

2.3.bean

2.3.1.定義

由 Spring IoC 容器管理的對(duì)象稱為 Bean,Bean 根據(jù) Spring 配置文件中的信息創(chuàng)建??梢园?Spring IoC 容器看作是一個(gè)大工廠,Bean 相當(dāng)于工廠的產(chǎn)品,如果希望這個(gè)大工廠生產(chǎn)和管理 Bean,則需要告訴容器需要哪些 Bean,以及需要哪種方式裝配 Bean。

Spring 配置文件支持兩種格式,即 XML 文件格式和 Properties 文件格式。

  • Properties 配置文件主要以 key-value 鍵值對(duì)的形式存在,只能賦值,不能進(jìn)行其他操作,適用于簡(jiǎn)單的屬性配置。
  • XML 配置文件是樹形結(jié)構(gòu),相對(duì)于 Properties 文件來說更加靈活。XML 配置文件結(jié)構(gòu)清晰,但是內(nèi)容比較繁瑣,適用于大型復(fù)雜的項(xiàng)目。

通常情況下,Spring 的配置文件使用 XML 格式。XML 配置文件的根元素是 ,該元素包含了多個(gè)子元素 。每一個(gè) 元素都定義了一個(gè) Bean,并描述了該 Bean 如何被裝配到 Spring 容器中。

2.3.2.創(chuàng)建

2.3.2.1 默認(rèn)方式

無參

<!-- 1. 默認(rèn)構(gòu)造函數(shù),如果類中沒有默認(rèn)構(gòu)造函數(shù)則無法創(chuàng)建對(duì)象;bean標(biāo)簽中只有id和class就默認(rèn)使用構(gòu)造函數(shù)創(chuàng)建對(duì)象 -->
<bean id="userService" class="com.wyl.pojo.User"/>

有參

<!-- 第一種根據(jù)index參數(shù)下標(biāo)設(shè)置 -->
<bean id="userService" class="com.wyl.pojo.User">
    <!-- index指構(gòu)造方法 , 下標(biāo)從0開始 -->
    <constructor-arg index="0" value="wyl"/>
</bean>
 
<!-- 第二種根據(jù)參數(shù)名字設(shè)置 -->
<bean id="userService" class="com.wyl.pojo.User">
    <!-- name指參數(shù)名 -->
    <constructor-arg name="name" value="wyl"/>
</bean>
<!-- 第三種根據(jù)參數(shù)類型設(shè)置 -->
<bean id="userService" class="com.wyl.pojo.User">
    <constructor-arg type="java.lang.String" value="wyl"/>
</bean>
2.3.2.2 工廠類中的方法
<!-- 2. 使用工廠中的方法創(chuàng)建對(duì)象;工廠中有一個(gè)方法可以創(chuàng)建對(duì)象,先創(chuàng)建工廠對(duì)象,通過factory-bean指向工廠,使用factory-method方法獲取對(duì)象 -->
<bean id="beanFactory" class="org.factory.BeanFactory"/>
<bean id="userService" factory-bean="beanFactory" factory-method="getUserService"/>
2.3.2.3 靜態(tài)工廠中的靜態(tài)方法
<!-- 3. 使用靜態(tài)工廠中的靜態(tài)方法創(chuàng)建對(duì)象 -->
<bean id="userService" class="org.factory.StaticBeanFactory" factory-method="getUserService"/>

2.3.2.配置

2.3.2.1.別名
<!--  別名 : 如果添加了別名,我們也可以使用別名獲取到這個(gè)對(duì)象 -->
<alias name="User" alias="u1"></alias>
2.3.2.2.bean 別名
<!--
  bean標(biāo)簽常用屬性:

id屬性:起名稱,id屬性值名稱任意命名,不能包含特殊符號(hào)
class屬性:創(chuàng)建對(duì)象所在類的全路徑
name屬性:功能和id屬性一樣的,但是在name屬性值里面可以包含特殊符號(hào)
scope屬性
singleton:默認(rèn)值,單例
prototype:多例
request:創(chuàng)建對(duì)象把對(duì)象放到request域里面
session:創(chuàng)建對(duì)象把對(duì)象放到session域里面
globalSession:創(chuàng)建對(duì)象把對(duì)象放到globalSession里面
  -->
<bean id="UserT" class="com.wyl.pojo.User" scope="singleton" name="u2 u21,u22;u23">
    <property name="name" value="123"/>
</bean>
2.3.2.3.import

團(tuán)隊(duì)的合作通過import來實(shí)現(xiàn) .

<import resource="beans.xml"/>

能將多個(gè)人開發(fā)的不同的配置xml文件整合到applicationContext.xml文件中,并且能夠合適的去重。

2.3.3.作用域

<bean id="..." class="..." scope="singleton"/>

Spring 容器在初始化一個(gè) Bean 實(shí)例時(shí),同時(shí)會(huì)指定該實(shí)例的作用域。Spring 5 支持以下 6 種作用域。

singleton

默認(rèn)值,單例模式,表示在 Spring 容器中只有一個(gè) Bean 實(shí)例,Bean 以單例的方式存在。

prototype

原型模式,表示每次通過 Spring 容器獲取 Bean 時(shí),容器都會(huì)創(chuàng)建一個(gè) Bean 實(shí)例。

request

每次 HTTP 請(qǐng)求,容器都會(huì)創(chuàng)建一個(gè) Bean 實(shí)例。該作用域只在當(dāng)前 HTTP Request 內(nèi)有效。

session

同一個(gè) HTTP Session 共享一個(gè) Bean 實(shí)例,不同的 Session 使用不同的 Bean 實(shí)例。該作用域僅在當(dāng)前 HTTP Session 內(nèi)有效。

application

同一個(gè) Web 應(yīng)用共享一個(gè) Bean 實(shí)例,該作用域在當(dāng)前 ServletContext 內(nèi)有效。
類似于 singleton,不同的是,singleton 表示每個(gè) IoC 容器中僅有一個(gè) Bean 實(shí)例,而同一個(gè) Web 應(yīng)用中可能會(huì)有多個(gè) IoC 容器,但一個(gè) Web 應(yīng)用只會(huì)有一個(gè) ServletContext,也可以說 application 才是 Web 應(yīng)用中貨真價(jià)實(shí)的單例模式。

websocket

websocket 的作用域是 WebSocket ,即在整個(gè) WebSocket 中有效
equest、session、application、websocket 和 global Session 作用域只能在 Web 環(huán)境下使用,如果使用 ClassPathXmlApplicationContext 加載這些作用域中的任意一個(gè)的 Bean,就會(huì)拋出以下異常。

2.3.4.生命周期

  1. Spring 啟動(dòng),查找并加載需要被 Spring 管理的 Bean,并實(shí)例化 Bean。
  2. 利用依賴注入完成 Bean 中所有屬性值的配置注入。
  3. 如果 Bean 實(shí)現(xiàn)了 BeanNameAware 接口,則 Spring 調(diào)用 Bean 的 setBeanName() 方法傳入當(dāng)前 Bean 的 id 值。
  4. 如果 Bean 實(shí)現(xiàn)了 BeanFactoryAware 接口,則 Spring 調(diào)用 setBeanFactory() 方法傳入當(dāng)前工廠實(shí)例的引用。
  5. 如果 Bean 實(shí)現(xiàn)了 ApplicationContextAware 接口,則 Spring 調(diào)用 setApplicationContext() 方法傳入當(dāng)前 ApplicationContext 實(shí)例的引用。
  6. 如果 Bean 實(shí)現(xiàn)了 [BeanPostProcessor] 接口,則 Spring 調(diào)用該接口的預(yù)初始化方法 postProcessBeforeInitialzation() 對(duì) Bean 進(jìn)行加工操作,此處非常重要,Spring 的 AOP 就是利用它實(shí)現(xiàn)的。
  7. 如果 Bean 實(shí)現(xiàn)了 InitializingBean 接口,則 Spring 將調(diào)用 afterPropertiesSet() 方法。
  8. 如果在配置文件中通過 init-method 屬性指定了初始化方法,則調(diào)用該初始化方法。
  9. 如果 [BeanPostProcessor ]和 Bean 關(guān)聯(lián),則 Spring 將調(diào)用該接口的初始化方法 postProcessAfterInitialization()。此時(shí),Bean 已經(jīng)可以被應(yīng)用系統(tǒng)使用了。
  10. 如果在 中指定了該 Bean 的作用域?yàn)?singleton,則將該 Bean 放入 Spring IoC 的緩存池中,觸發(fā) Spring 對(duì)該 Bean 的生命周期管理; 如果在 中指定了該 Bean 的作用域?yàn)?prototype,則將該 Bean 交給調(diào)用者,調(diào)用者管理該 Bean 的生命周期,Spring 不再管理該 Bean。
  11. 如果 Bean 實(shí)現(xiàn)了 DisposableBean 接口,則 Spring 會(huì)調(diào)用 destory() 方法銷毀 Bean;如果在配置文件中通過 destory-method 屬性指定了 Bean 的銷毀方法,則 Spring 將調(diào)用該方法對(duì) Bean 進(jìn)行銷毀。
2.3.4.1.單例
public class UserBean {
	private String name;  
    
    public UserBean(){  
        System.out.println("UserBean()構(gòu)造函數(shù)");  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        System.out.println("setName()");  
        this.name = name;  
    }  
    public void init(){  
        System.out.println("this is init of UserBean");  
    }  
      
    public void destory(){  
        System.out.println("this is destory of UserBean " + this);  
    }  
}
<bean id="user_singleton" class="com.wyl.userBean" scope="singleton" 
			init-method="init" destroy-method="destory" lazy-init="true"/>

當(dāng)scope="singleton",即默認(rèn)情況下,會(huì)在啟動(dòng)容器時(shí)(即實(shí)例化容器時(shí))時(shí)實(shí)例化。但我們可以指定Bean節(jié)點(diǎn)的lazy-init="true"來延遲初始化bean,這時(shí)候,只有在第一次獲取bean時(shí)才會(huì)初始化bean,即第一次請(qǐng)求該bean時(shí)才初始化.

如果想對(duì)所有的默認(rèn)單例bean都應(yīng)用延遲初始化,可以在根節(jié)點(diǎn)beans設(shè)置default-lazy-init屬性為true,如下所示:

<beans default-lazy-init="true">
public class LifeTest {
	@Test 
	public void test() {
		AbstractApplicationContext container = 
		new ClassPathXmlApplicationContext("user.xml");
		UserBean user = (UserBean)container.getBean("user_singleton");
		System.out.println(user);
		container.close();
	}
}

UserBean()構(gòu)造函數(shù)
this is init of UserBean
com.wyl.UserBean@573f2bb1
……
this is destory of UserBeancom.wyl.UserBean@573f2bb1

默認(rèn)情況下,Spring在讀取xml文件的時(shí)候,就會(huì)創(chuàng)建對(duì)象。在創(chuàng)建對(duì)象的時(shí)候先調(diào)用構(gòu)造器[UserBean(),然后調(diào)用init-method屬性值中所指定的方法。對(duì)象在被銷毀的時(shí)候,會(huì)調(diào)用destroy-method屬性值中所指定的方法.

2.3.4.2.非單例管理的對(duì)象

當(dāng)scope="prototype"時(shí),容器也會(huì)延遲初始化bean,Spring讀取xml文件的時(shí)候,并不會(huì)立刻創(chuàng)建對(duì)象,而是在第一次請(qǐng)求該bean時(shí)才初始化(如調(diào)用getBean方法時(shí))。

在第一次請(qǐng)求每一個(gè)prototype的bean時(shí),Spring容器都會(huì)調(diào)用其構(gòu)造器創(chuàng)建這個(gè)對(duì)象,然后調(diào)用init-method屬性值中所指定的方法。對(duì)象銷毀的時(shí)候,Spring容器不會(huì)幫我們調(diào)用任何方法,因?yàn)槭欠菃卫?,這個(gè)類型的對(duì)象有很多個(gè),Spring容器一旦把這個(gè)對(duì)象交給你之后,就不再管理這個(gè)對(duì)象了。

<bean id="user_prototype" class="com.bean.UserBean" scope="prototype" init-method="init" destroy-method="destroy"/>

public class UserTest {
	@Test 
	public void test() {
		AbstractApplicationContext container = new ClassPathXmlApplicationContext("User.xml");
		UserBean User1 = (UserBean)container.getBean("User_singleton");
		System.out.println(User1);
		
		UserBean User2 = (UserBean)container.getBean("User_prototype");
		System.out.println(User2);
		container.close();
	}
}

結(jié)果

UserBean()構(gòu)造函數(shù)
this is init of UserBean
com.wyl.UserBean@573f2bb1
LifeBean()構(gòu)造函數(shù)
this is init of UserBean
com.wyl.UserBean@5ae9a829
……
this is destory of lifeBean com.wyl.UserBean@573f2bb1

2.4.DI(依賴注入)

依賴注入Dependency Injection,在解耦的過程中,我們將對(duì)象的創(chuàng)建交給Spring容器管理,當(dāng)我們需要用其他類的對(duì)象,由Spring提供,我們只需在配置文件里聲明即可。A類使用B類,就產(chǎn)生依賴關(guān)系,Spring給我們解決依賴關(guān)系就是依賴注入(DI)

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

private String name;
private Integer age;
private Date birthday;
// 構(gòu)造函數(shù)
public UserServiceImpl(String name, Integer age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
<!-- name:按字段名稱輔助;index:字段索引,給第幾個(gè)字段賦值;type:指定注入值的類型,該類型也是構(gòu)造函數(shù)中某個(gè)或某些字段的類型; -->
<!-- value:要注入的值,基本類型和String;ref:注入其他類型數(shù)據(jù),指向外部bean對(duì)象;這個(gè)外部bean需要存在于Spring容器 -->
<bean id="userService" class="org.service.impl.UserServiceImpl">
    <constructor-arg name="name" value="張三"/>
    <constructor-arg name="age" value="12"/>
    <constructor-arg name="birthday" ref="date"/>
</bean>
<!-- 創(chuàng)建日期對(duì)象 -->
<bean id="date" class="java.util.Date"/>

2.4.2.Set方式注入

private String name;
private Integer age;
private Date birthday;
public void setName(String name) {
    this.name = name;
}

public void setAge(Integer age) {
    this.age = age;
}

public void setBirthday(Date birthday) {
    this.birthday = birthday;
}
<bean id="userService2" class="org.service.impl.UserServiceImpl2">
    <property name="name" value="李四"/>
    <property name="age" value="12"/>
    <property name="birthday" ref="date"/>
</bean>
<!-- 創(chuàng)建日期對(duì)象 -->
<bean id="date" class="java.util.Date"/>

2.4.3.對(duì)象類型注入

<!-- 注入對(duì)象類型屬性 -->
<!-- 1 配置service和dao對(duì)象 -->
<bean id="userDao" class="cn.ioc.UserDao"></bean>
<bean id="userService" class="cn.ioc.UserService">
    <!-- 注入dao對(duì)象-->
    <property name="userDao" ref="userDao"></property>
</bean>

2.4.4.復(fù)雜類型注入

<!-- 注入復(fù)雜類型屬性值 -->
  <bean id="person" class="cn.property.Person">
    <!-- 數(shù)組 -->
    <property name="arrs">
       <list>
         <value>小王</value>
         <value>小馬</value>
         <value>小宋</value>
       </list>
    </property>
    
    <!-- list -->
    <property name="list">
       <list>
         <value>小奧</value>
         <value>小金</value>
         <value>小普</value>
       </list>      
    </property>

    <!-- map -->
    <property name="map">
       <map>
         <entry key="aa" value="lucy"></entry>
         <entry key="bb" value="mary"></entry>
         <entry key="cc" value="tom"></entry>
       </map>
    </property>

    <!-- properties -->
    <property name="properties">
       <props>
         <prop key="driverclass">com.mysql.jdbc.Driver</prop>
         <prop key="username">root</prop>
       </props>
    </property>
  </bean>
<!--set-->
<property name="set">
            <set>
                <value>LOL</value>
                <value>COC</value>
                <value>WOW</value>
            </set>
</property>
<!--null-->
<property name="marne">
            <null/>
</property>

2.4.5.拓展方式注入

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

p命名注入 property

<!-- p命名空間注入,可以直接注入屬性的值:property -->
<bean id="User"  class="com.wyl.pojo.User" p:name ="老秦" p:age ="18"/>

c命名空間注入 constructor

<!-- c命名空間注入,通過構(gòu)造器注入:construct-args -->
<bean id="User2" class="com.wyl.pojo.User" c:age="18" c:name="老李"/>

注意點(diǎn):p命名和c命名不能直接使用,需要導(dǎo)入xml約束

2.5.自動(dòng)裝配

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

在Spring中有三種裝配的方式

  1. 在xml中顯示的配置
  2. 在java中顯示配置
  3. 隱式的自動(dòng)裝配bean

名稱 說明
no 默認(rèn)值,表示不使用自動(dòng)裝配,Bean 依賴必須通過 ref 元素定義。
byName 根據(jù) Property 的 name 自動(dòng)裝配,如果一個(gè) Bean 的 name 和另一個(gè) Bean 中的 Property 的 name 相同,則自動(dòng)裝配這個(gè) Bean 到 Property 中。
byType 根據(jù) Property 的數(shù)據(jù)類型(Type)自動(dòng)裝配,如果一個(gè) Bean 的數(shù)據(jù)類型兼容另一個(gè) Bean 中 Property 的數(shù)據(jù)類型,則自動(dòng)裝配。
constructor 類似于 byType,根據(jù)構(gòu)造方法參數(shù)的數(shù)據(jù)類型,進(jìn)行 byType 模式的自動(dòng)裝配。
autodetect(3.0版本不支持) 如果 Bean 中有默認(rèn)的構(gòu)造方法,則用 constructor 模式,否則用 byType 模式。

2.5.1.byName

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

2.5.2.byType

<bean id="cat" class="com.wyl.pojo.Cat"/>
    <bean id="dog" class="com.wyl.pojo.Dog"/>
    <!--
    byName:會(huì)自動(dòng)在容器上下文中查找,和自己對(duì)象set方法后面的值對(duì)應(yīng)的beanid!
    byType:會(huì)自動(dòng)在容器上下文中查找,和自己對(duì)象屬性類型相同的bean!
    -->
    <bean id="people" class="com.wyl.pojo.People" autowire="byType">
        <property name="name" value="WANGAYNLING"/>
    </bean>

2.5.3.注解

jdk1.5支持的注解,Spring2.5就支持注解了!

要使用注解須知:

  1. 導(dǎo)入約束 context約束
  2. 配置注解的支持: context:annotation-config/
<?xml version="1.0" encoding="UTF-8"?>
<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

@Autowired是按類型自動(dòng)轉(zhuǎn)配的,不支持id匹配。byType
需要導(dǎo)入 spring-aop的包!
直接在屬性上使用即可!也可以在set方式上使用!

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

 @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
@Nullable     // 字段標(biāo)記了這個(gè)注解,說明這個(gè)字段可以為null

或者 如果顯示定義了Autowired的required 的屬性為false ,說明這個(gè)對(duì)象可以為null,允許為空

autowired 注解應(yīng)該是只能是別的,當(dāng)注入 在IOC容器中該類型只有一個(gè)時(shí),就通過byType進(jìn)行裝配,當(dāng)注入容器存在多個(gè)同意類型的對(duì)象是,就是根據(jù)byName進(jìn)行裝配

如果@Autowired自動(dòng)裝配的環(huán)境比較復(fù)雜,自動(dòng)裝配無法通過一個(gè)注解[@Autowired]完成的時(shí)候,我們可以使用@Qualifier(value=“XXX”)去配置@Autowired的使用,指定一個(gè)唯一的bean對(duì)象注入。

@Qualifier

@Autowired是根據(jù)類型自動(dòng)裝配的,加上@Qualifier則可以根據(jù)byName的方式自動(dòng)裝配
@Qualifier不能單獨(dú)使用。

public class People {
    private String name;
    @Autowired
    @Qualifier("cat")
    private Cat cat;
    @Autowired
    @Qualifier("dog")
    private Dog dog;
}

@Resource注解

@Resource如有指定的name屬性,先按該屬性進(jìn)行byName方式查找裝配;

其次再進(jìn)行默認(rèn)的byName方式進(jìn)行裝配;

如果以上都不成功,則按byType的方式自動(dòng)裝配。

都不成功,則報(bào)異常。

public class People {
    private String name;
    @Resource(name = "cat")
    private Cat cat;
    @Resource(name = "dog")
    private Dog dog;

小結(jié)

  • @Autowired與@Resource異同:
  • @Autowired與@Resource都可以用來裝配bean。都可以寫在字段上,或?qū)懺趕etter方法上。
  • @Autowired默認(rèn)按類型裝配(屬于spring規(guī)范),默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null 值,可以設(shè)置它的required屬性為false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用
  • @Resource(屬于J2EE復(fù)返),默認(rèn)按照名稱進(jìn)行裝配,名稱可以通過name屬性進(jìn)行指定。如果沒有指定name屬性,當(dāng)注解寫在字段上時(shí),默認(rèn)取字段名進(jìn)行按照名稱查找,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配。當(dāng)找不到與名稱匹配的bean時(shí)才按照類型進(jìn)行裝配。但是 需要注意的是,如果name屬性一旦指定,就只會(huì)按照名稱進(jìn)行裝配。

它們的作用相同都是用注解方式注入對(duì)象,但執(zhí)行順序不同。@Autowired先byType,@Resource先byName。

2.6.ioc注解

@注解名稱(屬性名稱=屬性值)

2.6.1. Spring使用的注解大全和解釋

注解 解釋
@Controller 組合注解(組合了@Component注解),應(yīng)用在MVC層(控制層),DispatcherServlet會(huì)自動(dòng)掃描注解了此注解的類,然后將web請(qǐng)求映射到注解了@RequestMapping的方法上。
@Service 組合注解(組合了@Component注解),應(yīng)用在service層(業(yè)務(wù)邏輯層)
@Repository 組合注解(組合了@Component注解),應(yīng)用在dao層(數(shù)據(jù)訪問層)
@Component 表示一個(gè)帶注釋的類是一個(gè)“組件”,成為Spring管理的Bean。當(dāng)使用基于注解的配置和類路徑掃描時(shí),這些類被視為自動(dòng)檢測(cè)的候選對(duì)象。同時(shí)@Component還是一個(gè)元注解。
@Autowired Spring提供的工具(由Spring的依賴注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自動(dòng)注入。)
@Resource JSR-250提供的注解
@Inject JSR-330提供的注解
@Configuration 聲明當(dāng)前類是一個(gè)配置類(相當(dāng)于一個(gè)Spring配置的xml文件)
@ComponentScan 自動(dòng)掃描指定包下所有使用@Service,@Component,@Controller,@Repository的類并注冊(cè)
@Bean 注解在方法上,聲明當(dāng)前方法的返回值為一個(gè)Bean。返回的Bean對(duì)應(yīng)的類中可以定義init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定義,在構(gòu)造之后執(zhí)行init,在銷毀之前執(zhí)行destroy。
@Aspect 聲明一個(gè)切面(就是說這是一個(gè)額外功能)
@After 后置建言(advice),在原方法前執(zhí)行。
@Before 前置建言(advice),在原方法后執(zhí)行。
@Around 環(huán)繞建言(advice),在原方法執(zhí)行前執(zhí)行,在原方法執(zhí)行后再執(zhí)行(@Around可以實(shí)現(xiàn)其他兩種advice)
@PointCut 聲明切點(diǎn),即定義攔截規(guī)則,確定有哪些方法會(huì)被切入
@Transactional 聲明事務(wù)(一般默認(rèn)配置即可滿足要求,當(dāng)然也可以自定義)
@Cacheable 聲明數(shù)據(jù)緩存
@EnableAspectJAutoProxy 開啟Spring對(duì)AspectJ的支持
@Value 值得注入。經(jīng)常與Sping EL表達(dá)式語(yǔ)言一起使用,注入普通字符,系統(tǒng)屬性,表達(dá)式運(yùn)算結(jié)果,其他Bean的屬性,文件內(nèi)容,網(wǎng)址請(qǐng)求內(nèi)容,配置文件屬性值等等
@PropertySource 指定文件地址。提供了一種方便的、聲明性的機(jī)制,用于向Spring的環(huán)境添加PropertySource。與@configuration類一起使用。
@PostConstruct 標(biāo)注在方法上,該方法在構(gòu)造函數(shù)執(zhí)行完成之后執(zhí)行。
@PreDestroy 標(biāo)注在方法上,該方法在對(duì)象銷毀之前執(zhí)行。
@Profile 表示當(dāng)一個(gè)或多個(gè)指定的文件是活動(dòng)的時(shí),一個(gè)組件是有資格注冊(cè)的。使用@Profile注解類或者方法,達(dá)到在不同情況下選擇實(shí)例化不同的Bean。@Profile(“dev”)表示為dev時(shí)實(shí)例化。
@EnableAsync 開啟異步任務(wù)支持。注解在配置類上。
@Async 注解在方法上標(biāo)示這是一個(gè)異步方法,在類上標(biāo)示這個(gè)類所有的方法都是異步方法。
@EnableScheduling 注解在配置類上,開啟對(duì)計(jì)劃任務(wù)的支持。
@Scheduled 注解在方法上,聲明該方法是計(jì)劃任務(wù)。支持多種類型的計(jì)劃任務(wù):cron,fixDelay,fixRate
@Conditional 根據(jù)滿足某一特定條件創(chuàng)建特定的Bean
@Enable* 通過簡(jiǎn)單的@Enable來開啟一項(xiàng)功能的支持。所有@Enable注解都有一個(gè)@Import注解,@Import是用來導(dǎo)入配置類的,這也就意味著這些自動(dòng)開啟的實(shí)現(xiàn)其實(shí)是導(dǎo)入了一些自動(dòng)配置的Bean(1.直接導(dǎo)入配置類2.依據(jù)條件選擇配置類3.動(dòng)態(tài)注冊(cè)配置類)
@RunWith 這個(gè)是Junit的注解,springboot集成了junit。一般在測(cè)試類里使用:@RunWith(SpringJUnit4ClassRunner.class) — SpringJUnit4ClassRunner在JUnit環(huán)境下提供Sprng TestContext Framework的功能
@ContextConfiguration 用來加載配置ApplicationContext,其中classes屬性用來加載配置類:@ContextConfiguration(classes = {TestConfig.class(自定義的一個(gè)配置類)})
@ActiveProfiles 用來聲明活動(dòng)的profile–@ActiveProfiles(“prod”(這個(gè)prod定義在配置類中))
@EnableWebMvc 用在配置類上,開啟SpringMvc的Mvc的一些默認(rèn)配置:如ViewResolver,MessageConverter等。同時(shí)在自己定制SpringMvc的相關(guān)配置時(shí)需要做到兩點(diǎn):1.配置類繼承WebMvcConfigurerAdapter類2.就是必須使用這個(gè)@EnableWebMvc注解。
@RequestMapping 用來映射web請(qǐng)求(訪問路徑和參數(shù)),處理類和方法的??梢宰⒔庠陬惡头椒ㄉ希⒔庠诜椒ㄉ系腀RequestMapping路徑會(huì)繼承注解在類上的路徑。同時(shí)支持Serlvet的request和response作為參數(shù),也支持對(duì)request和response的媒體類型進(jìn)行配置。其中有value(路徑),produces(定義返回的媒體類型和字符集),method(指定請(qǐng)求方式)等屬性。
@ResponseBody 將返回值放在response體內(nèi)。返回的是數(shù)據(jù)而不是頁(yè)面
@RequestBody 允許request的參數(shù)在request體中,而不是在直接鏈接在地址的后面。此注解放置在參數(shù)前。
@PathVariable 放置在參數(shù)前,用來接受路徑參數(shù)。
@RestController 組合注解,組合了@Controller和@ResponseBody,當(dāng)我們只開發(fā)一個(gè)和頁(yè)面交互數(shù)據(jù)的控制層的時(shí)候可以使用此注解。
@ControllerAdvice 用在類上,聲明一個(gè)控制器建言,它也組合了@Component注解,會(huì)自動(dòng)注冊(cè)為Spring的Bean。
@ExceptionHandler 用在方法上定義全局處理,通過他的value屬性可以過濾攔截的條件:@ExceptionHandler(value=Exception.class)–表示攔截所有的Exception。
@ModelAttribute 將鍵值對(duì)添加到全局,所有注解了@RequestMapping的方法可獲得次鍵值對(duì)(就是在請(qǐng)求到達(dá)之前,往model里addAttribute一對(duì)name-value而已)。
@InitBinder 通過@InitBinder注解定制WebDataBinder(用在方法上,方法有一個(gè)WebDataBinder作為參數(shù),用WebDataBinder在方法內(nèi)定制數(shù)據(jù)綁定,例如可以忽略request傳過來的參數(shù)Id等)。
@WebAppConfiguration 一般用在測(cè)試上,注解在類上,用來聲明加載的ApplicationContext是一個(gè)WebApplicationContext。他的屬性指定的是Web資源的位置,默認(rèn)為src/main/webapp,我們可以修改為:@WebAppConfiguration(“src/main/resources”)。
@EnableAutoConfiguration 此注釋自動(dòng)載入應(yīng)用程序所需的所有Bean——這依賴于Spring Boot在類路徑中的查找。該注解組合了@Import注解,@Import注解導(dǎo)入了EnableAutoCofigurationImportSelector類,它使用SpringFactoriesLoader.loaderFactoryNames方法來掃描具有META-INF/spring.factories文件的jar包。而spring.factories里聲明了有哪些自動(dòng)配置。
@SpingBootApplication SpringBoot的核心注解,主要目的是開啟自動(dòng)配置。它也是一個(gè)組合注解,主要組合了@Configurer,@EnableAutoConfiguration(核心)和@ComponentScan??梢酝ㄟ^@SpringBootApplication(exclude={想要關(guān)閉的自動(dòng)配置的類名.class})來關(guān)閉特定的自動(dòng)配置。
@ImportResource 雖然Spring提倡零配置,但是還是提供了對(duì)xml文件的支持,這個(gè)注解就是用來加載xml配置的。例:@ImportResource({“classpath
@ConfigurationProperties 將properties屬性與一個(gè)Bean及其屬性相關(guān)聯(lián),從而實(shí)現(xiàn)類型安全的配置。例:@ConfigurationProperties(prefix=”authot”,locations={“classpath
@ConditionalOnBean 條件注解。當(dāng)容器里有指定Bean的條件下。
@ConditionalOnClass 條件注解。當(dāng)類路徑下有指定的類的條件下。
@ConditionalOnExpression 條件注解?;赟pEL表達(dá)式作為判斷條件。
@ConditionalOnJava 條件注解?;贘VM版本作為判斷條件。
@ConditionalOnJndi 條件注解。在JNDI存在的條件下查找指定的位置。
@ConditionalOnMissingBean 條件注解。當(dāng)容器里沒有指定Bean的情況下。
@ConditionalOnMissingClass 條件注解。當(dāng)類路徑下沒有指定的類的情況下。
@ConditionalOnNotWebApplication 條件注解。當(dāng)前項(xiàng)目不是web項(xiàng)目的條件下。
@ConditionalOnResource 條件注解。類路徑是否有指定的值。
@ConditionalOnSingleCandidate 條件注解。當(dāng)指定Bean在容器中只有一個(gè),后者雖然有多個(gè)但是指定首選的Bean。
@ConditionalOnWebApplication 條件注解。當(dāng)前項(xiàng)目是web項(xiàng)目的情況下。
@EnableConfigurationProperties 注解在類上,聲明開啟屬性注入,使用@Autowired注入。例:@EnableConfigurationProperties(HttpEncodingProperties.class)。
@AutoConfigureAfter 在指定的自動(dòng)配置類之后再配置。例:@AutoConfigureAfter(WebMvcAutoConfiguration.class)

2.6.1.1.創(chuàng)建對(duì)象的注解
  • @Component(標(biāo)注當(dāng)前類是Spring容器中的一個(gè)組件)
  • @Repository(一般用于持久層)
  • @Service(一般用于業(yè)務(wù)層)
  • @Controller(一般用于表現(xiàn)層)
2.6.1.2.注入數(shù)據(jù)的注解
  • @Autowired:自動(dòng)按類型注入,常用在變量上;如果容器中有唯一一個(gè)類型與注解的變量類型相同則可以自動(dòng)注入成功。當(dāng)有多個(gè)bean匹配則按照變量名稱去查找,找不到則注入失敗。
  • @Qualifier("userDaoImpl"):結(jié)合@Autowired使用,注入指定名稱的bean;在類的成員變量上不能單獨(dú)使用;在方法參數(shù)里使用可以單獨(dú)使用;
  • @Resource:相當(dāng)于@Autowired自動(dòng)注入,而@Resource(name="xxx")注入指定的bean,相當(dāng)于同時(shí)使用@Autowired和@Qualifier("userDaoImpl")兩個(gè)注解。

上面三個(gè)注解都只能注入其他的bean類型,不能注入基本數(shù)據(jù)類型和String和復(fù)雜類型;復(fù)雜類型只能通過xml文件來注入。

  • @Value:注入基本數(shù)據(jù)類型和String類型。指定數(shù)據(jù)的值,寫法:${表達(dá)式}。
2.6.1.3.改變作用范圍的注解

@Scope:取值有singleton單例(默認(rèn))和prototype多例

2.6.1.4.和生命周期相關(guān)注解
@PostConstruct
public void init() {
    System.out.println("初始化注解");
}
@PreDestroy
public void destroy() {
    System.out.println("銷毀注解");
}

這兩個(gè)注解和bean標(biāo)簽里面的init-method、destroy-method作用相同。

2.6.1.5.新注解
  • @Configuration:作用在類上面標(biāo)明當(dāng)前類是一個(gè)配置類
  • @ComponentScan(basePackages = "com.wyl"):掃描包注解:相當(dāng)于下面這一行配置

<!--<context:component-scan base-package="com.wyl"/>-->

  • @Bean:在配置類中寫在方法上,將方法返回的對(duì)象注入到Spring容器中。該注解的方法有參數(shù)時(shí),會(huì)去容器中找bean對(duì)象,跟@Autowired注解一樣的。
  • @PropertySource("classpath:db.properties"):指定數(shù)據(jù)庫(kù)配置文件的位置
  • @Import:存在多個(gè)配置文件,用該注解引入其他配置文件。
2.6.1.6.Spring測(cè)試注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ApplicationConfig.class) 純注解
// @ContextConfiguration(locations = "classpath:ApplicationContext.xml") xml配置文件
public class SpringTest {

    @Autowired
    private AccountServiceImpl accountService;

    @Test
    public void findAll(){
        List<Account> accountList = accountService.findAll();
        for (Account account : accountList) {
            System.out.println(account);
        }
    }
   
}

@RunWith(SpringJUnit4ClassRunner.class):替換掉原來junit的runner執(zhí)行方法,使用Spring自己的執(zhí)行方法。

@ContextConfiguration(classes = ApplicationConfig.class):如果是使用注解創(chuàng)建Spring的容器使用classes;

@ContextConfiguration(locations = "classpath:ApplicationContext.xml"):使用xml配置文件的方法

2.6.2.基于xml方式創(chuàng)建bean

public class User {
    private Integer id;
    private String name;
}
<?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.wyl.bean.User" >
        <property name="id" value="1"></property>
        <property name="name" value="wyl"></property>
    </bean>
</beans>
@test
public void UserTest{
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("Bean.xml");
        User userInfo=(User)context.getBean("user");
        System.out.println(userInfo);
}

2.6.3.基于@Configuration 和@Bean 注解

Configuration 配置類

@Configuration
public class MyTestConfig {
    //bean的id默認(rèn)為方法名
    @Bean
    public User user(){
        User user =new User();
        user.setName("王延領(lǐng)");
        user.setId(2);
        return user;
    }
}
@test
public void UserTest{
    AnnotationConfigApplicationContext context=new 							AnnotationConfigApplicationContext(MyTestConfig.class);
        User userInfo=(User)context.getBean("user");
        System.out.println(userInfo.toString());
        }

3.Spring核心AOP

AOP(Aspect Oriented Programming):面向切面編程,在不修改源代碼的情況下增強(qiáng)代碼的功能。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

3.1.AOP實(shí)現(xiàn)原理代理模式

代理模式,創(chuàng)建一個(gè)代理對(duì)象實(shí)現(xiàn)和被對(duì)代理對(duì)象相同的接口,這樣就擁有和被代理對(duì)象相同的功能,在這基礎(chǔ)上增強(qiáng)原有的方法。

  • 靜態(tài)代理,手動(dòng)去實(shí)現(xiàn)一個(gè)代理類
  • 動(dòng)態(tài)代理,通過反射動(dòng)態(tài)的實(shí)現(xiàn)代理類

3.1.1 靜態(tài)代理

步驟:

  • 1.抽象角色 : 一般使用接口或者抽象類來實(shí)現(xiàn)
public interface Rent {
    public void rent();
}
  • 2.真實(shí)角色 : 被代理的角色
public class Host implements Rent{
    @Override
    public void rent() {
        System.out.println("房東出租房子!");
    }
}
  • 3.代理角色 : 代理真實(shí)角色 ; 代理真實(shí)角色后 , 一般會(huì)做一些附屬的操作 .
public class Proxy {
    private Host host;
    public Proxy(){
 
    }
    public Proxy(Host host){
        this.host=host;
    }
    public void rent(){
        seeHouse();
 
        host.rent();
        hetong();
        fare();
    }
    public void seeHouse(){
        System.out.println("中介帶你看房");
    }
    public void fare(){
        System.out.println("收中介費(fèi)!");
    }
    public void hetong(){
        System.out.println("簽租領(lǐng)合同");
    } 
 
}
  • 4.客戶 : 使用代理角色來進(jìn)行一些操作 .
public class Client {
    public static void main(String[] args) {
        Host host=new Host();
        //host.rent();
        Proxy proxy=new Proxy(host);
        proxy.rent();
    }
}

好處:

  1. 可以使得我們的真實(shí)角色更加純粹 . 不再去關(guān)注一些公共的事情 .
  2. 公共的業(yè)務(wù)由代理來完成 . 實(shí)現(xiàn)了業(yè)務(wù)的分工 ,
  3. 公共業(yè)務(wù)發(fā)生擴(kuò)展時(shí)變得更加集中和方便 .

缺點(diǎn) :

  • 類多了 , 多了代理類 , 工作量變大了 . 開發(fā)效率降低 .

我們想要靜態(tài)代理的好處,又不想要靜態(tài)代理的缺點(diǎn),所以 , 就有了動(dòng)態(tài)代理

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

動(dòng)態(tài)代理的代理類是動(dòng)態(tài)生成的 . 靜態(tài)代理的代理類是我們提前寫好的

動(dòng)態(tài)代理分為兩類 :

  • 基于接口的動(dòng)態(tài)代理----JDK動(dòng)態(tài)代理
//抽象角色:租房
public interface Rent {
    public void rent();
}
//真實(shí)角色: 房東,房東要出租房子
public class Host implements Rent{
    public void rent() {
        System.out.println("房屋出租");
    }
}
//代理:中介
public class ProxyInvocationHandler implements InvocationHandler {
    private Rent rent;
 
    public void setRent(Rent rent) {
        this.rent = rent;
    }
 
    //生成代理類,重點(diǎn)是第二個(gè)參數(shù),獲取要代理的抽象角色!之前都是一個(gè)角色,現(xiàn)在可以代理一類角色
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                rent.getClass().getInterfaces(),this);
    }
 
    // proxy : 代理類 method : 代理類的調(diào)用處理程序的方法對(duì)象.
    // 處理代理實(shí)例上的方法調(diào)用并返回結(jié)果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        //核心:本質(zhì)利用反射實(shí)現(xiàn)!
        Object result = method.invoke(rent, args);
        fare();
        return result;
    }
 
    //看房
    public void seeHouse(){
        System.out.println("帶房客看房");
    }
    //收中介費(fèi)
    public void fare(){
        System.out.println("收中介費(fèi)");
    }
}
//租客
public class Client {
 
    public static void main(String[] args) {
        //真實(shí)角色
        Host host = new Host();
        //代理實(shí)例的調(diào)用處理程序
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setRent(host); //將真實(shí)角色放置進(jìn)去!
        Rent proxy = (Rent)pih.getProxy(); //動(dòng)態(tài)生成對(duì)應(yīng)的代理類!
        proxy.rent();
    }
 
}
  • 基于類的動(dòng)態(tài)代理–cglib
// 被代理的對(duì)象
Account account = new Account();
Account o = (Account) Enhancer.create(account.getClass(), new MethodInterceptor() {
    /**
    * 被代理對(duì)象的方法執(zhí)行前會(huì)執(zhí)行
    * @param obj 被代理的對(duì)象
    * @param method 方法
    * @param objects 參數(shù)
    * @param methodProxy 當(dāng)前執(zhí)行方法的代理的對(duì)象
    * @return 和被代理對(duì)象的方法相同的返回值
    * @throws Throwable 異常
    */
    @Override
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("增強(qiáng)前...");
        Object invoke = method.invoke(account, objects);
        System.out.println("增強(qiáng)后...");
        return invoke;
    }
});
o.findAll();

3.2.AOP術(shù)語(yǔ)

  • Joinpoint(連接點(diǎn)):指的是方法,可以被動(dòng)態(tài)代理增強(qiáng)的方法就是連接點(diǎn),Spring只支持方法類型的連接點(diǎn)
  • Pointcut(切入點(diǎn)):定義要對(duì)哪些Joinpoint連接點(diǎn)(方法)進(jìn)行攔截增強(qiáng)功能。被增強(qiáng)的方法叫做切入點(diǎn),所有的方法都可以看做是一個(gè)連接點(diǎn)。只有被增強(qiáng)了的方法才叫做切入點(diǎn)。
  • Advice(通知/增強(qiáng)):攔截到Jointpoint(連接點(diǎn))之后要做的事情就是通知。通知的類型:前置通知、后置通知、最終通知、環(huán)繞通知、異常通知。
  • Introduction(引介):一種特殊的通知,在不修改代碼的前提下,可以在運(yùn)行期為類動(dòng)態(tài)的添加一些方法或字段。
  • Target(目標(biāo)對(duì)象):代理的目標(biāo)對(duì)象
  • Weaving(織入):是把增強(qiáng) 應(yīng)用到 目標(biāo)對(duì)象來創(chuàng)建新的代理對(duì)象的過程(添加新功能代碼的過程)。Spring采用的是動(dòng)態(tài)代理織入,而AspectJ采用編譯期和類裝載織入。
  • Proxy(代理):一個(gè)類被AOP織入增強(qiáng)后,就產(chǎn)生一個(gè)結(jié)果代理類。
  • Aspect(切面):是切入點(diǎn)和通知(引介)的結(jié)合。

3.3.使用Spring實(shí)現(xiàn)Aop

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

3.3.1.通過 Spring API 實(shí)現(xiàn)

//接口與業(yè)務(wù)
public interface UserService {
 
    public void add();
 
    public void delete();
 
    public void update();
 
    public void search();
 
} 
public class UserServiceImpl implements UserService{
 
    @Override
    public void add() {
        System.out.println("增加用戶");
    }
 
    @Override
    public void delete() {
        System.out.println("刪除用戶");
    }
 
    @Override
    public void update() {
        System.out.println("更新用戶");
    }
 
    @Override
    public void search() {
        System.out.println("查詢用戶");
    }
}
//增強(qiáng)
public class AfterLog implements AfterReturningAdvice {
    //returnValue 返回值
    //method被調(diào)用的方法
    //args 被調(diào)用的方法的對(duì)象的參數(shù)
    //target 被調(diào)用的目標(biāo)對(duì)象
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("執(zhí)行了" + target.getClass().getName()
        +"的"+method.getName()+"方法,"
        +"返回值:"+returnValue);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
 
    <!--注冊(cè)bean-->
    <bean id="userService" class="com.wyl.service.UserServiceImpl"/>
    <bean id="log" class="com.kuang.log.Log"/>
    <bean id="afterLog" class="com.kuang.log.AfterLog"/>
 
    <!--aop的配置-->
    <aop:config>
        <!--切入點(diǎn)  expression:表達(dá)式匹配要執(zhí)行的方法-->
        <aop:pointcut id="pointcut" expression="execution(* com.wyl.service.UserServiceImpl.*(..))"/>
        <!--執(zhí)行環(huán)繞; advice-ref執(zhí)行方法 . pointcut-ref切入點(diǎn)-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
 
</beans>
public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.search();
    }
}

3.3.2.自定義類來實(shí)現(xiàn)Aop

//切入類
public class DiyPointcut {
 
    public void before(){
        System.out.println("---------方法執(zhí)行前---------");
    }
    public void after(){
        System.out.println("---------方法執(zhí)行后---------");
    }
    
}
<!--第二種方式自定義實(shí)現(xiàn)-->
<!--注冊(cè)bean-->
<bean id="diy" class="com.wyl.config.DiyPointcut"/
<!--aop的配置-->
<aop:config>
    <!--第二種方式:使用AOP的標(biāo)簽實(shí)現(xiàn)-->
    <aop:aspect ref="diy">
        <aop:pointcut id="diyPonitcut" expression="execution(* com.wyl.service.UserServiceImpl.*(..))"/>
        <aop:before pointcut-ref="diyPonitcut" method="before"/>
        <aop:after pointcut-ref="diyPonitcut" method="after"/>
    </aop:aspect>
</aop:config>
public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
}

3.3.3.使用注解實(shí)現(xiàn)AOP

//注解實(shí)現(xiàn)的增強(qiáng)類
package com.wyl.config;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
 
@Aspect
public class AnnotationPointcut {
    @Before("execution(* com.wyl.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("---------方法執(zhí)行前---------");
    }
 
    @After("execution(* com.wyl.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("---------方法執(zhí)行后---------");
    }
 
    @Around("execution(* com.wyl.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("環(huán)繞前");
        System.out.println("簽名:"+jp.getSignature());
        //執(zhí)行目標(biāo)方法proceed
        Object proceed = jp.proceed();
        System.out.println("環(huán)繞后");
        System.out.println(proceed);
    }
}

4.事務(wù)和JdbcTemplate

4.1.JdbcTemplate使用

入門案例:

// Spring自帶的數(shù)據(jù)源
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/spring?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai");
dataSource.setUsername("root");
dataSource.setPassword("root");
JdbcTemplate template = new JdbcTemplate(dataSource);

List<Account> accountList = template.query("select * from account", new BeanPropertyRowMapper<>(Account.class));
for (Account account : accountList) {
    System.out.println(account);
}

具體增刪改查用法:

@Autowired
private JdbcTemplate jdbcTemplate;

// 添加
@Test
public void insert(){
    String sql = "insert into account(name, money) VALUES (?,?)";
    Account account1 = new Account();
    account1.setName("迪迦");
    account1.setMoney(10000F);
    jdbcTemplate.update(sql, account1.getName(), account1.getMoney());
    find();
}

// 刪除
@Test
public void delete(){
    String sql = "delete from account where id = ?";
    jdbcTemplate.update(sql, 6);
    find();
}

// 更新
@Test
public void update(){
    List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<>(Account.class), 1);
    Account account = accounts.get(0);
    account.setName("泰羅");
    String sql = "update account set name = ? where id = ?";
    jdbcTemplate.update(sql, account.getName(),account.getId());
    find();
}

// 查詢所有
@Test
public void find(){
    List<Account> accountList = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<>(Account.class));
    for (Account account : accountList) {
        System.out.println(account);
    }
}

// 查詢一個(gè)bean
@Override
public Account findByName(String name) {
    String sql = "select * from account where name = ?";
    return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Account.class), name);
}

// 查詢一個(gè)Object
@Test
public void findOne(){
    String sql = "select count(id) from account";
    Integer integer = jdbcTemplate.queryForObject(sql, Integer.class);
    System.out.println(integer);
}

4.2.Spring配置事務(wù)

在Spring中有兩種方法管理事務(wù):聲明式事務(wù)管理和編程式事務(wù)管理;

  • 聲明式事務(wù)管理:

1、xml配置文件式:

1、配置事務(wù)管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/></bean>

2、配置通知
<!-- 配置事務(wù)的通知/增強(qiáng) -->
<tx:advice id="interceptor">
    <!-- 配置事務(wù)的屬性 -->
    <!-- isolation:事務(wù)隔離級(jí)別,默認(rèn)使用數(shù)據(jù)庫(kù)的隔離級(jí)別
         no-rollback-for:指定一個(gè)異常,除了該異常都回滾。
         propagation:事務(wù)傳播行為,默認(rèn)是required一定有事務(wù),增刪改設(shè)置required,查詢?cè)O(shè)置supports
         read-only:是否只讀。只有查詢才能設(shè)置true。默認(rèn)是false支持讀寫。
         rollback-for:指定一個(gè)異常,出現(xiàn)該異常就回滾,其他異常不回滾。
         timeout:事務(wù)超時(shí)時(shí)間,默認(rèn)-1,永不超時(shí)。指定了以秒為單位。 -->
    <tx:attributes>
        <!-- 指定在哪種規(guī)則的方法上添加事務(wù) -->
        <tx:method name="transfer*"/>
    </tx:attributes>
</tx:advice>

3、事務(wù)管理器和切入點(diǎn)表達(dá)式關(guān)聯(lián)起來
<aop:config>
    <!-- service包下所有類的所有方法都添加事務(wù) -->
    <aop:pointcut id="commonPointcut" expression="execution(* com.sample.service.*.*(..))"/>
    <!-- 將事務(wù)管理器和切入點(diǎn)表達(dá)式關(guān)聯(lián)起來 -->
    <aop:advisor advice-ref="interceptor" pointcut-ref="commonPointcut"/>
</aop:config>

2、注解式:

1、配置事務(wù)管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/></bean>

2、開啟對(duì)事務(wù)注解的支持
<!-- 開啟對(duì)事務(wù)注解的支持 -->
<tx:annotation-driven/>

3、在要添加事物的類上添加注解:@Transactional

3、純注解式

@Configuration
@ComponentScan("com.sample")
// 相當(dāng)于<tx:annotation-driven/>
@EnableTransactionManagement
@PropertySource("classpath:db.properties")
public class AppConfig {

    @Value("${db.driver}")
    private String driver;
    @Value("${db.url}")
    private String url;
    @Value("${db.username}")
    private String username;
    @Value("${db.password}")
    private String password;

    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }

    @Bean
    public DataSourceTransactionManager transactionManager(){
        return new DataSourceTransactionManager(dataSource());
    }

}

==========
在類上添加@Transactional注解即可
  • 編程式事務(wù)管理:通過代碼去實(shí)現(xiàn)事務(wù)的管理,手動(dòng)開啟事務(wù)、提交、回滾。

到此這篇關(guān)于初學(xué)者,Spring快速入門的文章就介紹到這了,更多相關(guān)Spring 入門內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的List集合框架之Vector詳細(xì)解析

    Java的List集合框架之Vector詳細(xì)解析

    這篇文章主要介紹了Java的List集合框架之Vector詳細(xì)解析,List接口繼承Collection,Collection繼承于Iterable,List接口實(shí)現(xiàn)類分為Vector、ArrayList、LinkedList,Vector底層是一個(gè)Object數(shù)組,需要的朋友可以參考下
    2023-11-11
  • java poi sax方式處理大數(shù)據(jù)量excel文件

    java poi sax方式處理大數(shù)據(jù)量excel文件

    這篇文章主要介紹了java poi sax方式處理大數(shù)據(jù)量excel文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 深入淺析jni中的java接口使用

    深入淺析jni中的java接口使用

    這篇文章主要介紹了jni中的java接口使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 在Mac OS上安裝Tomcat服務(wù)器的教程

    在Mac OS上安裝Tomcat服務(wù)器的教程

    這篇文章主要介紹了在Mac OS上安裝Tomcat服務(wù)器的教程,方便進(jìn)行工作環(huán)境下的Java web開發(fā),需要的朋友可以參考下
    2015-11-11
  • JPA @Query時(shí),無法使用limit函數(shù)的問題及解決

    JPA @Query時(shí),無法使用limit函數(shù)的問題及解決

    這篇文章主要介紹了JPA @Query時(shí),無法使用limit函數(shù)的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java反射校驗(yàn)參數(shù)是否是基礎(chǔ)類型步驟示例

    java反射校驗(yàn)參數(shù)是否是基礎(chǔ)類型步驟示例

    這篇文章主要為大家介紹了java反射校驗(yàn)參數(shù)是否是基礎(chǔ)類型步驟示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java獲取指定字符串出現(xiàn)次數(shù)的方法

    Java獲取指定字符串出現(xiàn)次數(shù)的方法

    這篇文章主要為大家詳細(xì)介紹了Java獲取指定字符串出現(xiàn)次數(shù)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • binarySearch在java的查找實(shí)例用法

    binarySearch在java的查找實(shí)例用法

    在本篇文章里小編給大家整理的是一篇關(guān)于binarySearch在java的查找實(shí)例用法,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-02-02
  • java使用bitmap實(shí)現(xiàn)可回收自增id的示例

    java使用bitmap實(shí)現(xiàn)可回收自增id的示例

    本文主要介紹了java使用bitmap實(shí)現(xiàn)可回收自增id的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 解析Java和IDEA中的文件打包問題

    解析Java和IDEA中的文件打包問題

    這篇文章主要介紹了Java和IDEA中的文件打包問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07

最新評(píng)論