第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
  • 設(shè)值注入,通過(guò)set的方式注入,自動(dòng)的調(diào)用類的set方法給屬性賦值

    查看全部
    0 采集 收起 來(lái)源:Spring注入方式

    2019-08-30

  • 通過(guò)xml的方式將bean加載到容器,通過(guò)xml來(lái)獲取bean

    查看全部
    0 采集 收起 來(lái)源:IOC及Bean容器

    2019-08-30

  • 類自動(dòng)檢測(cè)及Bean的注冊(cè):

    <context:component-scan base-package="org.example"/>

    查看全部
  • Spring注解:@Configuration,@Bean,@Import,@DependsOn

    @Component是一個(gè)通用注解,可以作為元注解,可用于任何bean

    @Repository -DAO層

    @Service - Service層

    @controller -Controller層

    查看全部
  • Bean的生命周期:定義,初始化,使用,銷毀

    //初始化?配置init-method
    <bean?id="initBean"?class="examples.ExampleBean"?init-method="init"></bean>
    
    //銷毀?配置destroy-method
    <bean?id="destroyBean"?class="examples.ExampleBean"?destroy-method="cleanup"></bean>


    查看全部
  • Spring 注入方式:設(shè)值注入,構(gòu)造注入

    查看全部
    0 采集 收起 來(lái)源:Spring注入方式

    2019-08-29

  • 接口:

    面向接口編程:

    接口是用于隱藏具體實(shí)現(xiàn)和實(shí)現(xiàn)多態(tài)性的組件

    接口實(shí)現(xiàn)的變動(dòng)不影響各層間的調(diào)用,

    風(fēng)情層次級(jí)調(diào)用關(guān)系,每層只向外提供一組件功能接口,各層僅依賴接口而非實(shí)現(xiàn)類

    查看全部
    0 采集 收起 來(lái)源:IOC及Bean容器

    2019-08-28

  • 課程內(nèi)容:

    什么是框架?

    Spring簡(jiǎn)介

    IOC配置注解

    Bean配置注解

    AOP配置注解,AspectJ,API

    查看全部
  • ioc:控制反轉(zhuǎn),控制權(quán)的轉(zhuǎn)移,應(yīng)該是程序本身不負(fù)責(zé)依賴對(duì)象的創(chuàng)建和維護(hù),而是由外部容器負(fù)責(zé)創(chuàng)建和維護(hù)。

    di:依賴注入是一種實(shí)現(xiàn)方式

    查看全部
    0 采集 收起 來(lái)源:IOC及Bean容器

    2019-08-27

  • Spring中把所有的對(duì)象稱為bean

    查看全部
    0 采集 收起 來(lái)源:Spring注入方式

    2019-08-26

  • Spring的Ioc是通過(guò)外部容器來(lái)創(chuàng)建和維護(hù)對(duì)象, 而不是程序自己本身創(chuàng)建, 依賴注入是其實(shí)現(xiàn)方式, 本質(zhì)是為了實(shí)現(xiàn)降低耦合度的目的.

    查看全部
    0 采集 收起 來(lái)源:Spring注入方式

    2019-08-26

  • 旮旯
    查看全部
  • 元注解,@component

    查看全部
  • Maven

    (1)是一個(gè)可以通過(guò)一小段描述信息來(lái)管理項(xiàng)目的構(gòu)建、報(bào)告和文檔的軟件項(xiàng)目管理工具

    (2)作用:在文件中添加相應(yīng)的配置,maven就可以自動(dòng)下載對(duì)應(yīng)的jar包;該jar包依賴的jar包也會(huì)被自動(dòng)下載下來(lái);可以直接通過(guò)他打包壓縮文件或jar項(xiàng)目

    1°下載jar包

    Maven項(xiàng)目有一個(gè)pom.xml文件,只要添加對(duì)應(yīng)的配置,就可以自動(dòng)下載jar包。

    在代碼中,對(duì)于一個(gè)<dependency>結(jié)點(diǎn),其中有

    項(xiàng)目名:<groupId>junit</groupId>

    項(xiàng)目模塊:<artifactId>junit</artifactId>

    項(xiàng)目版本:<version>4.8.2</version>

    來(lái)對(duì)應(yīng)的下載jar包

    2°尋找和下載依賴的jar包

    3°熱部署,熱依賴

    在web項(xiàng)目已經(jīng)運(yùn)行時(shí),修改代碼可以直接被web服務(wù)器接受,不需要重啟服務(wù)器或重新部署代碼;可以直接通過(guò)maven打包war或jar項(xiàng)目

    ?

    pom.xml解析

    xsi全名:xml schema instance 即xml架構(gòu)實(shí)例

    xmlns是web.xml文件用到的命名空間

    xmlns:xsi是指web.xml遵守xml規(guī)范

    xsi:schemaLocation是指具體用到的schema資源?

    properties指常量,在pom的其它地方可以直接引用

    dependencies 依賴關(guān)系

    build構(gòu)建配置

    plugins插件列表

    depositories倉(cāng)庫(kù)配置

    distributionManagement 分發(fā)配置

    profile“用戶配置文件”是針對(duì)每個(gè)帳戶的數(shù)據(jù)存儲(chǔ)

    ?

    Nginx

    Nginx同Apache一樣都是一種WEB服務(wù)器?;赗EST架構(gòu)風(fēng)格,以統(tǒng)一資源描述符(Uniform Resources Identifier, URI)或者統(tǒng)一資源定位符(Uniform Resources Locator, URL)作為溝通依據(jù),通過(guò)HTTP協(xié)議提供各種網(wǎng)絡(luò)服務(wù)。

    Apache是重量級(jí)的、不支持高并發(fā)、性能差,作為替代品,Nginx應(yīng)運(yùn)而生。

    Nginx是一款自由的、開(kāi)源的、高性能的HTTP服務(wù)器和反向代理服務(wù)器;同時(shí)也是一個(gè)IMAP、POP3、SMTP代理服務(wù)器;Nginx可以作為一個(gè)HTTP服務(wù)器進(jìn)行網(wǎng)站的發(fā)布處理,另外Nginx可以作為反向代理進(jìn)行負(fù)載均衡的實(shí)現(xiàn)。

    ?

    JavaBean

    1.JavaBean是使用Java語(yǔ)言開(kāi)發(fā)的一個(gè)可重用的組件,在開(kāi)發(fā)中可以使用JavaBean減少重復(fù)代碼,使整個(gè)代碼的開(kāi)發(fā)更簡(jiǎn)潔

    2.一個(gè)類中只包含屬性、setter、getter方法,那么這種類就成為簡(jiǎn)單JavaBean。

    簡(jiǎn)單JavaBean的名詞:

    (1)VO:與簡(jiǎn)單Java對(duì)象對(duì)應(yīng),專門用于傳遞值的操作上

    (2)POJO:簡(jiǎn)單Java對(duì)象

    (3)TO:傳輸對(duì)象,進(jìn)行遠(yuǎn)程傳輸時(shí),對(duì)象所在的類必須實(shí)現(xiàn)java.io.Serializable接口。

    3.Web項(xiàng)目中的目錄:

    WEB-INF:Web目錄中最安全的文件夾,保存各種類、第三方j(luò)ar包、配置文件

    Web.xml:Web的部署描述符

    4.xml文件,表示可擴(kuò)展標(biāo)記語(yǔ)言,是一種很像HTML的標(biāo)記語(yǔ)言,旨在傳輸數(shù)據(jù)而不是顯示數(shù)據(jù)。

    5.web.xml

    web.xml文件并不是web工程必須的。

    web.xml文件是用來(lái)初始化配置信息:比如Welcome頁(yè)面、servlet、servlet-mapping、filter、listener、啟動(dòng)加載級(jí)別等。

    ?

    JSON

    JSON是一種取代XML的數(shù)據(jù)結(jié)構(gòu),和xml相比,它更小巧但描述能力卻不差,由于它的小巧所以網(wǎng)絡(luò)傳輸數(shù)據(jù)將減少更多流量從而加快速度,

    那么,JSON到底是什么?

    JSON就是一串字符串 只不過(guò)元素會(huì)使用特定的符號(hào)標(biāo)注。

    {} 雙括號(hào)表示對(duì)象

    [] 中括號(hào)表示數(shù)組

    "" 雙引號(hào)內(nèi)是屬性或值

    : 冒號(hào)表示后者是前者的值(這個(gè)值可以是字符串、數(shù)字、也可以是另一個(gè)數(shù)組或?qū)ο?

    所以 {"name": "Michael"} 可以理解為是一個(gè)包含name為Michael的對(duì)象

    而[{"name": "Michael"},{"name": "Jerry"}]就表示包含兩個(gè)對(duì)象的數(shù)組

    當(dāng)然了,你也可以使用{"name":["Michael","Jerry"]}來(lái)簡(jiǎn)化上面一部,這是一個(gè)擁有一個(gè)name數(shù)組的對(duì)象

    ?

    GSON

    GSON是Google提供的用來(lái)在Java對(duì)象和JSON數(shù)據(jù)之間進(jìn)行映射的Java類庫(kù)??梢詫⒁粋€(gè)Json字符轉(zhuǎn)成一個(gè)Java對(duì)象,或者將一個(gè)Java轉(zhuǎn)化為Json字符串。

    GSON的創(chuàng)建方式:

    (1)Gson gson = new gson();

    (2)通過(guò)GsonBuilder()配置多種配置

    Gson gson = new GsonBuilder().配置方法().create();

    方法:

    public String toJson(Object obj):將對(duì)象轉(zhuǎn)換為JSON字符串?

    public T fromJson(String jsonStr, T.class):將JSON字符串轉(zhuǎn)換為java對(duì)象

    ?

    servlet

    實(shí)質(zhì)就是運(yùn)行在 Web 應(yīng)用服務(wù)器上的 Java 程序,與普通 Java 程序不同,它是位于 Web 服務(wù)器內(nèi)部的服務(wù)器端的 Java 應(yīng)用程序,可以對(duì) Web 瀏覽器或其他 HTTP 客戶端程序發(fā)送的請(qǐng)求進(jìn)行處理。

    ? Servlet的框架是由兩個(gè)Java包組成:javax.servlet和javax.servlet.http. 在javax.servlet包中定義了所有的Servlet類都必須實(shí)現(xiàn)或擴(kuò)展的的通用接口和類.在javax.servlet.http包中定義了采用HTTP通信協(xié)議的HttpServlet類.

    ? 廣義的servlet指實(shí)現(xiàn)了Servlet接口的類,一般情況下Servlet用來(lái)拓展基于HTTP協(xié)議的Web服務(wù)器。編寫一個(gè) Servlet 其實(shí)就是按照 Servlet 規(guī)范編寫一個(gè) Java 類。

    Servlet沒(méi)有main方法,它的對(duì)象的運(yùn)行需要Servlet容器(Web容器)的支持,它的創(chuàng)建、使用、銷毀都由Servlet容器進(jìn)行管理(如Tomcat)。Servlet被部署到Servlet容器中,由容器來(lái)實(shí)例化和調(diào)方法。

    有了 Servlet 之后,用戶通過(guò)單擊某個(gè)鏈接或者直接在瀏覽器的地址欄中輸入 URL 來(lái)訪問(wèn) Servlet ,Web 服務(wù)器接收到該請(qǐng)求后,并不是將請(qǐng)求直接交給 Servlet ,而是交給 Servlet 容器。Servlet 容器實(shí)例化 Servlet ,調(diào)用 Servlet 的一個(gè)特定方法對(duì)請(qǐng)求進(jìn)行處理, 并產(chǎn)生一個(gè)響應(yīng)。這個(gè)響應(yīng)由 Servlet 容器返回給 Web 服務(wù)器,Web 服務(wù)器包裝這個(gè)響應(yīng),以 HTTP 響應(yīng)的形式發(fā)送給 Web 瀏覽器。

    Servlet是和HTTP協(xié)議緊密聯(lián)系的,它可以處理HTTP協(xié)議相關(guān)的所有內(nèi)容。這也是Servlet應(yīng)用廣泛的原因之一?

    Servlet的主要作用功能:接受從瀏覽器發(fā)送過(guò)來(lái)的HTTP請(qǐng)求(request),并返回HTTP響應(yīng)(response)。這個(gè)工作是在service方法中完成的。要獲取客戶端提交的數(shù)據(jù)需通過(guò)request,要想容器輸出數(shù)據(jù)需通過(guò)response。

    ?

    Servlet工作原理解析:一個(gè)HTTP請(qǐng)求的執(zhí)行過(guò)程:

    客戶端發(fā)出請(qǐng)求http://localhost:8080/xxx

    根據(jù)Web.xml文件的配置,找到<url-pattern>對(duì)應(yīng)的<servlet-mapping>

    讀取<servlet-mapping>中<servlet-name>的值

    找到<servlet-name>對(duì)應(yīng)的<servlet-class>

    找到該class并加載執(zhí)行該class

    ?

    在Web容器中,Servlet主要經(jīng)歷4個(gè)階段:

    (1)加載Servlet

    (2)初始化Servlet init()方法

    (3)處理請(qǐng)求service()方法

    (4)處理完成destory()方法

    ?

    開(kāi)發(fā)Servlet程序:

    (a)定義一個(gè)類HelloServlet,并讓該類去實(shí)現(xiàn)javax.servlet.Servlet接口;

    (b)實(shí)現(xiàn)Servlet接口中的init,service,destory等方法.

    ?

    配置 Servlet:

    上面編寫好的 HelloServlet 類僅僅是一個(gè)普通的實(shí)現(xiàn)類而已,而現(xiàn)在我想要它運(yùn)行在我自己的 Tomcat 服務(wù)器中,所以應(yīng)該通知 Tomcat 服務(wù)器來(lái)管理我的 HelloServlet 類

    ?

    Servlet 提供處理請(qǐng)求的方法:

    Servlet 即實(shí)現(xiàn)了 Servlet 接口的類,當(dāng)我們創(chuàng)建一個(gè)自定義類,實(shí)現(xiàn) Servlet 接口 的時(shí)候,會(huì)發(fā)現(xiàn)有 5 個(gè)方法需要重寫,有init【初始化】,destroy【銷毀】,service【服務(wù)】,ServletConfig【Servlet配置】,getServletInfo【Serlvet信息】。

    這樣做的話,我們每次都需要實(shí)現(xiàn) 5 個(gè)方法,太麻煩了!

    我們可以直接繼承 HttpServlet 類,該類已經(jīng)默認(rèn)實(shí)現(xiàn)了 Servlet 接口中的所有方法,在編寫 Servlet 的時(shí)候,你只需要重寫你需要的方法就好了。

    對(duì)于每次訪問(wèn)請(qǐng)求,Servlet引擎都會(huì)創(chuàng)建一個(gè)新的HttpServletRequest請(qǐng)求對(duì)象和一個(gè)新的HttpServletResponse響應(yīng)對(duì)象,然后將這兩個(gè)對(duì)象作為參數(shù)傳遞給它調(diào)用的Servlet的service()方法,service方法再根據(jù)請(qǐng)求方式分別調(diào)用doXXX方法。

    ?

    GET 和 POST 的區(qū)別:

    要知道,GET 和 POST 都是請(qǐng)求方式

    GET:

    瀏覽器器地址欄:http://localhost/test.html?name=wmyskxz&sex=male

    這里提交了兩個(gè)參數(shù),一個(gè)是name屬性值為wmyskxz,另一個(gè)是sex屬性值為male,這是一種直接的請(qǐng)求方式,在請(qǐng)求資源后面跟上 ? 符號(hào)與參數(shù)連接,其他的參數(shù)使用 & 符號(hào)連接。

    缺點(diǎn):

    1.暴露請(qǐng)求信息,不安全

    2.請(qǐng)求信息不能超過(guò)1kb,可傳輸?shù)男畔⒂邢蓿荒苌蟼鲌D片

    POST:

    瀏覽器地址欄:http://localhost/test.html#

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

    1.隱藏了請(qǐng)求信息,較安全(但仍可以通過(guò)相關(guān)工具訪問(wèn)到數(shù)據(jù))

    2.POST 方式?jīng)]有限制請(qǐng)求的數(shù)據(jù)大小,可以做圖片的上傳

    但并不是所有的數(shù)據(jù)都需要使用 POST 請(qǐng)求來(lái)完成,事實(shí)上,GET 請(qǐng)求方式會(huì)比 POST 請(qǐng)求更快,當(dāng)數(shù)據(jù)小并且安全性要求不是那么高的時(shí)候,GET 仍然是很好的選擇.(并且 GET 相較 POST 簡(jiǎn)單)

    ?

    MVC 模式

    MVC 是一種分層的設(shè)計(jì)模式 。

    M 代表 模型(Model)

    模型是什么呢? 模型就是數(shù)據(jù),就是dao,bean

    V 代表 視圖(View)

    視圖是什么呢? 就是網(wǎng)頁(yè), JSP,用來(lái)展示模型中的數(shù)據(jù)

    C 代表 控制器(controller)

    控制器是什么? 控制器的作用就是把不同的數(shù)據(jù)(Model),顯示在不同的視圖(View)上。

    ?

    HTTPServlet

    當(dāng)Web容器接收到某個(gè)Servlet請(qǐng)求時(shí),Servlet把請(qǐng)求封裝成一個(gè)HttpServletRequest對(duì)象,然后把對(duì)象傳給Servlet的對(duì)應(yīng)的服務(wù)方法.

    HTTP的請(qǐng)求方式包括DELETE(刪),GET(查),OPTIONS,POST(增),PUT(改)和TRACE,在HttpServlet類中分別提供了相應(yīng)的服務(wù)方法DoGet()等

    HttpServlet的功能:讀取Http請(qǐng)求的內(nèi)容。

    請(qǐng)求流程如下:

    1)Web客戶向Servlet容器發(fā)出Http請(qǐng)求;

    2)Servlet容器解析Web客戶的Http請(qǐng)求;

    3)Servlet容器創(chuàng)建一個(gè)HttpRequest對(duì)象,在這個(gè)對(duì)象中封裝Http請(qǐng)求信息;

    4)Servlet容器創(chuàng)建一個(gè)HttpResponse對(duì)象;

    5)Servlet容器調(diào)用HttpServlet的service方法,把HttpRequest和HttpResponse對(duì)象作為service方法的參數(shù)傳給HttpServlet對(duì)象;

    6)HttpServlet調(diào)用HttpRequest的有關(guān)方法,獲取HTTP請(qǐng)求信息;

    7)HttpServlet調(diào)用HttpResponse的有關(guān)方法,生成響應(yīng)數(shù)據(jù);

    8)Servlet容器把HttpServlet的響應(yīng)結(jié)果傳給Web客戶。

    ?

    Tomcat

    (1)輕量級(jí)Web應(yīng)用服務(wù)器(是一個(gè)Servlet/JSP容器,Servlet/JSP程序需要運(yùn)行在web容器上)。通俗來(lái)講,萬(wàn)維網(wǎng)的本質(zhì)是超文本文檔(HTML文檔)組成的一個(gè)通過(guò)超級(jí)鏈接互相訪問(wèn)交互網(wǎng)絡(luò),當(dāng)甲計(jì)算機(jī)上的文檔A通過(guò)超鏈接訪問(wèn)乙計(jì)算器上的文檔B,B必須放在Web服務(wù)器才能被訪問(wèn)

    (2)應(yīng)用程序是一個(gè)WAR(WebArchive)文件,根目錄下有Html和JSP文件或包含這兩種文件的目錄,還有一個(gè)WEB-INF目錄。WEB-INF目錄下有一個(gè)web.xml文件和一個(gè)classes目錄,web.xml是這個(gè)應(yīng)用的配置文件,classes目錄下則包含編譯好的Servlet類和Jsp或Servlet所依賴的其它類(如JavaBean)

    (3)還具有傳統(tǒng)的Web服務(wù)器的功能:處理Html頁(yè)面

    ?

    單元測(cè)試

    1.斷言

    (1)斷言:也就是所謂的assertion,是jdk1.4后加入的新功能。

    (2)它主要使用在代碼開(kāi)發(fā)和測(cè)試時(shí)期,用于對(duì)某些關(guān)鍵數(shù)據(jù)的判斷,如果這個(gè)關(guān)鍵數(shù)據(jù)不是你程序所預(yù)期的數(shù)據(jù),程序就提出警告或退出。java使用assert作為一個(gè)關(guān)鍵字

    (3)語(yǔ)法

    語(yǔ)法1:assert expression;???????????????

    //expression代表一個(gè)布爾類型的表達(dá)式,如果為真,就繼續(xù)正常運(yùn)行,如果為假,程序退出

    語(yǔ)法2:assert expression1 : expression2;??????????????????

    //expression1是一個(gè)布爾表達(dá)式,expression2是一個(gè)基本類型或者Object類型,如果expression1為真,則程序忽略expression2繼續(xù)運(yùn)行;如果expression1為假,則運(yùn)行expression2,然后退出程序。

    (4)斷言功能是用于軟件的開(kāi)發(fā)和測(cè)試的,也就是說(shuō),刪去斷言的那部分語(yǔ)句后,你程序的結(jié)構(gòu)和運(yùn)行不應(yīng)該有任何改變,千萬(wàn)不要把斷言當(dāng)成程序中的一個(gè)功能來(lái)使用

    2.Junit

    (1)是一個(gè)Java語(yǔ)言的單元測(cè)試框架

    (2)為什么要使用Junit:

    通常一個(gè)項(xiàng)目中有成千上萬(wàn)的方法,以前一般的做法是寫一些測(cè)試代碼看輸出結(jié)果,然后由自己來(lái)判斷結(jié)果是否正確,使用JUnit的好處就是這個(gè)結(jié)果是否正確的判斷是由JUnit來(lái)完成的。我們只要關(guān)注結(jié)果是否正確就可以了。測(cè)試框架可以幫助我們對(duì)編寫的程序進(jìn)行有目的性的測(cè)試,減少代碼中的bug,使用斷言機(jī)制直接將預(yù)期結(jié)果與實(shí)際結(jié)果對(duì)比,確保對(duì)結(jié)果的可預(yù)知性。

    (3)JUint包含:junit.jar和hamcrest-core.jar:設(shè)置匹配性規(guī)則的一個(gè)框架,可以有效增強(qiáng)JUnit測(cè)試的能力。

    (4)用IDEA進(jìn)行單元測(cè)試(對(duì)src的包下的已經(jīng)存在的類進(jìn)行):

    在src目錄下創(chuàng)建一個(gè)新的包test,再創(chuàng)建一個(gè)類,右鍵選中在按SHIFT+CTRL+ALT+S,選擇Modules的Dependencies右邊的綠色加號(hào),在IDEA的安裝目錄下找到lib下的兩個(gè)jar包:Junit-4.12和hamcrest-core-1.3。

    然后可以通過(guò)@Test注釋(需要導(dǎo)包org.junit.Test,將普通方法修飾為測(cè)試方法)來(lái)添加斷言方法,如:

    @Test

    public void testAdd() {

    ??? assertEquals(6, new Caculate().add(4,2));

    }

    其中assertEquals()方法是org.junit.Assert中的方法,可以用靜態(tài)導(dǎo)入(import static org.junit.Assert.*),如果期望值和實(shí)際值一致則沒(méi)問(wèn)題,如果不一致會(huì)拋出AssertError錯(cuò)誤。

    注意所有方法都是public void修飾的

    (5)Junit通過(guò)@BeforeClass @AfterClass @Before @After可以調(diào)用其他方法,其中快捷鍵ALT+INSERT中出現(xiàn)的setUp Method(@Before)為每個(gè)測(cè)試方法運(yùn)行前運(yùn)行的方法,tearDown Method(@After)為每個(gè)測(cè)試方法運(yùn)行后運(yùn)行的方法

    (6)Test有兩個(gè)屬性:@Test(expected=xx.class) ,如@Test(expected = ArithmeticException.class)則當(dāng)被除數(shù)為0是不會(huì)拋出算數(shù)異常(預(yù)期已經(jīng)拋出該異常)

    和@Test(timeout=毫秒) 超過(guò)該時(shí)間則結(jié)束

    (7)@Ingore修飾的方法不會(huì)被執(zhí)行

    (8)通過(guò)測(cè)試套件來(lái)組織測(cè)試類一起運(yùn)行

    @RunWith(Suite.class)

    @Suite.SuiteClasses({TaskTest1.class, TaskTest2.class})

    public class SuiteTest {

    ????? //…

    }

    該類是一個(gè)空類,通過(guò)@RunWith(Suite.class)來(lái)開(kāi)始批量測(cè)試,用@Suit.SuiteClasses來(lái)放入需要進(jìn)行測(cè)試的測(cè)試類

    (9)參數(shù)化設(shè)置,通過(guò)@RunWith(Parameterized.class)實(shí)現(xiàn)

    @Runwith(Parameterized.class)

    public class ParameterTest {

    ????? int expected = 0;

    ????? int input1 = 0;

    ????? int input2 = 0;

    ?

    ????? @Parameters

    ????? public static Collection<Object[]> t() {

    ?????????? return Arrays.asList(new Object[][] {

    ???????????????? {3,1,2},

    {4,2,2}

    });

    }

    ?

    public ParameterTest(int expected, int input1, int input2) {

    ????? this.expected = expected;

    ????? this.input1 = input1;

    ????? this.input2 = input2;

    }

    ?

    @Test

    public void testAdd() {

    ????? assertEquals(expected, new Calculate().add(input1,input2));

    }

    }

    先定義存放數(shù)據(jù)的變量,然后聲明一個(gè)返回值為Collection的靜態(tài)方法來(lái)存放數(shù)據(jù),然后提供一個(gè)構(gòu)造方法,最后寫一個(gè)測(cè)試方法。注意@RunWith()注釋中的是Parameterized的class對(duì)象

    ?

    JDBC

    JDBC(Java DataBase Connectivity)是Java和數(shù)據(jù)庫(kù)的橋梁

    編程步驟:

    (1)裝載數(shù)據(jù)庫(kù)的JDBC驅(qū)動(dòng)并進(jìn)行初始化

    1°導(dǎo)入jar包,如mysql-connector-java-5.0.8-bin.jar

    2°初始化驅(qū)動(dòng)類com.mysql.jdbc.Driver

    try {

    Class.forName("com.mysql.jdbc.Driver");

    } catch (ClassNotFoundException e) {

    e.printStackTrace();

    }

    (需要捕獲異常)

    (2)建立JDBC和數(shù)據(jù)庫(kù)之間的連接

    Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/exam?characterEncoding=UTF-8", "root", "admin");

    包括三個(gè)參數(shù)(URL,數(shù)據(jù)庫(kù)的用戶名,數(shù)據(jù)庫(kù)的密碼)

    其中URL包括jdbc:mysql://數(shù)據(jù)庫(kù)的主機(jī):端口/要操作的數(shù)據(jù)庫(kù)的名稱?編碼方式

    Connection接口必須在用完關(guān)閉

    (3)獲取Statement或PreparedStatement接口,來(lái)執(zhí)行sql語(yǔ)句

    Statement容易出錯(cuò),不常用

    增加 刪除 修改:

    String sql = “update t_course set course_name=? where courese_id=?”;???

    PreparedStatement ps = c.prepareStatement(sql);

    ps.setString(1, “chinese”);

    ps.setInt(2, 5);

    ps.executeUpdate();????? //增刪改都使用Update ;可以有返回值,標(biāo)識(shí)多少條數(shù)據(jù)受到了影響

    查詢:

    String sql = “select * from tb_user where id=?”;? //其中?是一個(gè)占位符,后面來(lái)對(duì)它賦值

    PreparedStatement ps = c.prepareStatement(sql);

    ps.setLong(1,1L);???? //給第一個(gè)占位符賦值為1L

    ResultSet rs = ps.executeQuery();???

    當(dāng)數(shù)據(jù)量比較大時(shí),可以使用批量添加

    for(int i=1; i<100; i++) {

    pstmt.setInt(1, 8000+i);

    pstmt.setString(2, "趙_"+i);

    ???? pstmt.addBatch();

    ????? //批量更新

    ???? if(i%10 == 0) {

    ???? ???? pstmt.executeBatch();

    ???? }

    }

    (4)執(zhí)行sql語(yǔ)句,如果有結(jié)果,將它返回集合ResultSet,并對(duì)結(jié)果進(jìn)行處理

    ResultSet rs = ps.executeQuery();???

    while(resultSet.next()) {?????? //遍歷結(jié)果

    ????? System.out.println(resultSet.getString("Name"));????? //根據(jù)括號(hào)中的屬性值得到結(jié)果

    ????? System.out.println(resultSet.getInt("age"));

    }

    (5)釋放資源(從里到外)

    if(rs != null) {

    ????? try {

    rs.close();

    }catch (SQLException e) {

    ??? ????? e.printStackTrace();

    }

    }

    if(ps != null) {

    try {

    rs.close();

    }catch (SQLException e) {

    ???? ???? e.printStackTrace();

    }

    }

    if(c != null) {

    try {

    rs.close();

    }catch (SQLException e) {

    ???? ???? e.printStackTrace();

    }

    }

    ?

    加密算法

    1.哈希算法:哈希算法是單向的,可以將任何大小的數(shù)據(jù)轉(zhuǎn)化為定長(zhǎng)的密文,而且無(wú)法被反向計(jì)算。另外,即使數(shù)據(jù)源只改動(dòng)了一丁點(diǎn),哈希的結(jié)果也會(huì)完全不同。這樣的特性使得它非常適合用于保存密碼。作為哈希函數(shù)的一種,MD5(消息摘要算法)被廣泛應(yīng)用,但是它所產(chǎn)生的哈希值非常弱,容易通過(guò)字典攻擊和暴力攻擊破解。

    2.密碼加鹽:鹽是在獲取密碼哈希值過(guò)程中添加到密碼的一段隨機(jī)序列,它能夠防止通過(guò)預(yù)先計(jì)算的彩虹表破解。每個(gè)用戶創(chuàng)建屬于自己的鹽,這樣一來(lái),即使用戶的密碼相同,通過(guò)加鹽后的哈希值也將不同。在獲取鹽值后,將用戶的原始密碼與鹽值一起加密得到密文。同時(shí)鹽值通常和密碼哈希值一起存放在賬戶數(shù)據(jù)庫(kù)中,或者直接存為哈希字符串的一部分。當(dāng)需要驗(yàn)證用戶的密碼時(shí),需要將鹽值取出,按照之前的加密規(guī)則與密碼一起重新加密,并驗(yàn)證兩次的密文是否相同。

    3.SHA(安全散列算法)和MD5相似,但是它產(chǎn)生的哈希值很強(qiáng),如SHA256算法的哈希值大小為256位。

    4.PBKDF2加密算法:全稱Password-Based Key Derivation Function,屬于哈希算法。它可以使哈希函數(shù)足夠慢以阻止攻擊,但仍然足夠快以至于不會(huì)對(duì)用戶造成明顯的延遲。PBKDF2算法使用SHA256作為偽隨機(jī)函數(shù),并對(duì)密碼加鹽,同時(shí)指定迭代次數(shù)來(lái)減慢暴力破解的速度,具有很強(qiáng)的安全性。在Java中的實(shí)現(xiàn)為PBKDF2WithHmacSHA1。

    ?

    MyBatis

    1.在Java中,對(duì)數(shù)據(jù)庫(kù)的常用工具是JDBC,它的工作量大,開(kāi)發(fā)者需要先注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)、建立數(shù)據(jù)庫(kù)連接、創(chuàng)建Statement對(duì)象來(lái)執(zhí)行sql語(yǔ)句、設(shè)置查詢參數(shù)、執(zhí)行查詢并將結(jié)果集返回ResultSet對(duì)象,解析結(jié)果集,最后還需要釋放資源。通過(guò)JDBC來(lái)訪問(wèn)數(shù)據(jù)庫(kù),每一次都需要進(jìn)行上述一些重復(fù)的繁雜的代碼。

    主要缺點(diǎn)如下:

    (1)? 頻繁的對(duì)數(shù)據(jù)庫(kù)創(chuàng)建和釋放連接接會(huì)造成系統(tǒng)資源的浪費(fèi)。

    (2)? sql語(yǔ)句寫在代碼里,屬于硬編碼,不易進(jìn)行維護(hù)。

    (3)? sql參數(shù)硬編碼,不易進(jìn)行維護(hù)。

    (4)? 對(duì)結(jié)果集的解析麻煩,需要開(kāi)發(fā)者自己去讀取并生成對(duì)應(yīng)的pojo對(duì)象。

    2.MyBatis對(duì)JDBC很好地進(jìn)行了封裝,解決了上述缺點(diǎn),分別如下:

    (1)? 在SqlMapConfig.xml配置文件中設(shè)置數(shù)據(jù)庫(kù)連接池,通過(guò)數(shù)據(jù)庫(kù)連接池來(lái)管理數(shù)據(jù)庫(kù)。

    (2)? 將sql語(yǔ)句配置在xxxmapper.xml文件中,與代碼分離。

    (3)? MyBatis自動(dòng)將java對(duì)象映射給sql語(yǔ)句。

    (4)? MyBatis自動(dòng)將sql語(yǔ)句的執(zhí)行結(jié)果映射給java對(duì)象

    3.Mybatis使用的主要步驟(使用傳統(tǒng)Dao的開(kāi)發(fā)方式):

    (1)? 導(dǎo)入依賴的jar包

    (2)? 配置MyBatis核心配置配置SqlMapConfig.xml,包括:

    a)使用properties導(dǎo)入連接數(shù)據(jù)庫(kù)的配置信息

    b)使用environment來(lái)配置JDBC事務(wù)管理器、數(shù)據(jù)庫(kù)連接池

    c)配置映射文件(將sqlSessionFactory注入到實(shí)現(xiàn)類)

    (3)? 配置log4j.properties文件

    (4)? 創(chuàng)建pojo類

    (5)? 創(chuàng)建Dao接口

    (6)? 創(chuàng)建DaoImpl實(shí)現(xiàn)類

    (7)? 創(chuàng)建Mapper映射文件xxx.xml,包括sql語(yǔ)句

    (8)? 進(jìn)行單元測(cè)試

    4.傳統(tǒng)Dao開(kāi)發(fā)的方式是在實(shí)現(xiàn)類中注入SqlSessionFactory并通過(guò)工廠類獲取SqlSession對(duì)象,缺點(diǎn)是在實(shí)現(xiàn)類中存在大量模板方法,并且調(diào)用SqlSession方法時(shí)存在硬編碼;使用Mapper代理的方式進(jìn)行開(kāi)發(fā),只需要寫dao接口(Mapper),而不需要寫dao實(shí)現(xiàn)類,由mybatis根據(jù)dao接口和映射文件中statement的定義生成接口實(shí)現(xiàn)代理對(duì)象。

    5.Mybatis使用的主要步驟(使用Mapper動(dòng)態(tài)代理的開(kāi)發(fā)方式):

    (1)? 導(dǎo)入依賴的jar包

    (2)? 配置MyBatis核心配置配置SqlMapConfig.xml,包括:

    a)使用properties導(dǎo)入連接數(shù)據(jù)庫(kù)的配置信息

    b)使用environment來(lái)配置JDBC事務(wù)管理器、數(shù)據(jù)庫(kù)連接池

    c)配置映射文件

    ????????? i.方法1:通過(guò)配置MapperFactoryBean類,將sqlSessionFactory注入到接口???????

    ????????? ii.方法2使用包掃描:通過(guò)MapperScannerConfigurer類將mapper接口所在的包賦給basePackage(比方法

    1更簡(jiǎn)單)

    (3)? 配置log4j.properties文件

    (4)? 創(chuàng)建pojo類

    (5)? 創(chuàng)建Mapper接口

    (6)? 創(chuàng)建xxxMapper.xml映射文件,包括sql語(yǔ)句,注意:

    a)namespace必須是接口的全路徑名

    b)接口的方法名必須與sql id 一致

    c)接口的入?yún)⒈仨毰cparameterType類型一致

    d)接口的返回值必須與resultType類型一致

    (7)? 進(jìn)行單元測(cè)試

    6.

    (1)使用Spring:

    Spring用來(lái)管理對(duì)象關(guān)系,可以根據(jù)配置文件來(lái)創(chuàng)建及組裝對(duì)象之間的依賴關(guān)系,Spring的面向切面編程能幫助我們無(wú)耦合地實(shí)現(xiàn)日志記錄、性能統(tǒng)計(jì)、安全控制等。

    (2)Spring整合MyBatis步驟:

    1°重新配置MaBatis的配置文件SqlMapConfig.xml,不再包含數(shù)據(jù)庫(kù)連接、數(shù)據(jù)庫(kù)連接池、SqlSessionFactory對(duì)象等內(nèi)容。

    2°創(chuàng)建Spring的配置文件applicationContext.xml,將SqlMapConfig.xml中刪除的內(nèi)容交給Spring來(lái)完成。


    查看全部
    0 采集 收起 來(lái)源:Advice擴(kuò)展

    2019-08-21

  • 第五章 Spring AOP基本概念

    主要內(nèi)容:

    什么是AOP及實(shí)現(xiàn)方式

    AOP基本概念

    Spring中的AOP

    AOP實(shí)現(xiàn)方式之Schema-based AOP(配置方式實(shí)現(xiàn))

    Spring AOP API

    AOP實(shí)現(xiàn)方式之AspectJ

    5-1 AOP基本概念及特點(diǎn)

    1.什么是AOP

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

    (2)主要的功能是:日志記錄、性能統(tǒng)計(jì)、安全控制、事務(wù)處理、異常處理等

    (3)切面,是與功能垂直的,比如日志要對(duì)每一個(gè)模塊的每一個(gè)點(diǎn)處都進(jìn)行記錄

    2.AOP的實(shí)現(xiàn)方式

    (1)預(yù)編譯

    如AspectJ

    (2)運(yùn)行期動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理、CGLib動(dòng)態(tài)代理)

    如SpringAOP、JbossAOP

    3.AOP相關(guān)概念

    (1)切面Aspect:一個(gè)關(guān)注點(diǎn)的模塊化,這個(gè)關(guān)注點(diǎn)可能會(huì)橫切(控制)多個(gè)對(duì)象

    (2)連接點(diǎn)Joinpoint:程序執(zhí)行過(guò)程中的某個(gè)特定的點(diǎn)

    (3)通知Advice:在切面的某個(gè)特定的連接點(diǎn)上(額外)執(zhí)行的動(dòng)作

    (4)切入點(diǎn)Pointcut:匹配連接點(diǎn)的斷言,在AOP中通知和一個(gè)切入點(diǎn)表達(dá)式關(guān)聯(lián)

    (5)引入Introduction:在不修改類代碼的前提下,為類添加新的方法和屬性(類似于編譯器將java文件編程為class文件)

    (6)目標(biāo)對(duì)象Target Object:被一個(gè)或多個(gè)切面通知的對(duì)象

    (7)AOP代理AOP Proxy:AOP框架創(chuàng)建的對(duì)象,用來(lái)實(shí)現(xiàn)奇恩契約(aspect contract)(包括通知方法執(zhí)行等功能)

    (8)織入Weaving:把切面連接到其它的應(yīng)用程序類型或者對(duì)象上,并創(chuàng)建一個(gè)被通知的對(duì)象,分為:編譯時(shí)織入、類加載時(shí)織入、執(zhí)行時(shí)織入

    4.通知Advice的類型

    (1)前置通知Before advice:在某連接點(diǎn)(join point)之前執(zhí)行的通知,但不能阻止連接點(diǎn)前的執(zhí)行(除非它拋出一個(gè)異常)

    (2)返回后通知After returning advice:在某連接點(diǎn)(join point)正常完成后執(zhí)行的通知

    (3)返回異常后通知After throwing advice:在方法拋出異常退出時(shí)執(zhí)行的通知

    (4)后通知After(finally) advice:當(dāng)某連接點(diǎn)退出時(shí)執(zhí)行的通知(不論是正常返回還是異常退出)

    (5)環(huán)繞通知Around Advice:包圍一個(gè)連接點(diǎn)(join point)的通知

    5.Spring框架中AOP的用途

    (1)提供了聲明式的企業(yè)服務(wù),特別是EJB的替代服務(wù)的聲明

    (2)允許用戶定制自己的切面,以完成OOP與AOP的互補(bǔ)使用

    6.Spring的AOP實(shí)現(xiàn)

    (1)純java實(shí)現(xiàn),無(wú)需特殊的編譯過(guò)程,不需要控制類加載器層次

    (2)目前只支持方法執(zhí)行連接點(diǎn)(通知Spring Bean的方法執(zhí)行)

    (3)不是為了提供最完整的AOP實(shí)現(xiàn)(盡管它非常強(qiáng)大);而是側(cè)重于提供一種AOP實(shí)現(xiàn)和Spring IoC容器之間的整合,用于幫助解決企業(yè)應(yīng)用中的常見(jiàn)問(wèn)題

    (4)Spring AOP不會(huì)與AspectJ競(jìng)爭(zhēng),從而提供綜合全面的AOP解決方案

    7.有接口和無(wú)接口的Spring AOP實(shí)現(xiàn)的區(qū)別

    (1)有接口:Spring AOP默認(rèn)使用標(biāo)準(zhǔn)的JavaSE動(dòng)態(tài)代理作為AOP代理,這使得任何接口(或接口集)都可以被代理

    (2)無(wú)接口:Spring AOP中也可以使用CGLIB代理(如果一個(gè)業(yè)務(wù)對(duì)象并沒(méi)有實(shí)現(xiàn)一個(gè)接口)

    ?

    下面內(nèi)容:Schema——基于配置的AOP實(shí)現(xiàn)

    5-2 配置切面aspect

    1.Spring所有的切面和通知器都必須放在一個(gè)<aop:config>內(nèi)(可以配置包含多個(gè)<aop:config>元素),每一個(gè)<aop:config>可以包含pointcut,advisor和aspect元素(它們必須按照這個(gè)順序進(jìn)行聲明)

    2.<aop:config>風(fēng)格的配置大量使用了Spring的自動(dòng)代理機(jī)制

    3.聲明aspect要用到<aop:config>和<aop:aspect>

    <aop:config>

    ????? <aop:aspect> id="myAspect" ref="aBean">

    ?????????? …

    ????? <aop:aspect>

    <aop:config>

    ?

    <bean id="aBean" class="…">

    ????? …

    </bean>

    ?

    5-3 配置切入點(diǎn)Pointcut

    1.聲明

    execution(public * *(..)):切入點(diǎn)為執(zhí)行所有public方法時(shí)

    execution(* set*(..)):切入點(diǎn)為執(zhí)行所有set開(kāi)始的方法

    execution(* com.xyz.service.AccountService.*(..)):切入點(diǎn)為執(zhí)行AccountService類中的所有方法時(shí)

    execution(* com.xyz.service..(..)):切入點(diǎn)為執(zhí)行com.xyz.service包下的所有方法時(shí)

    execution(* com.xyz.service…(..)):切入點(diǎn)為執(zhí)行com.xyz.service包及其子包下的所有方法時(shí)

    with(com.xyz.service.*)(only in Spring AOP)

    with(com.xyz.service..*)(only in Spring AOP) within用于匹配指定類型內(nèi)的方法執(zhí)行

    this(com.xyz.service.AccountService) (only in Spring AOP) this用于匹配當(dāng)前AOP代理對(duì)象類型的執(zhí)行方法

    等等很多,用的時(shí)候再查

    2.例子

    <aop:config>

    ????? <aop:pointcut id="businessService"

    //在執(zhí)行service包下的所有類的任何類型的方法時(shí),引入切入點(diǎn)

    ?????????? expression="execution(* com.xyz.myapp.service..(..))"/>

    </aop:config>

    <aop:config>

    ????? <aop:pointcut id="businessService"

    //在執(zhí)行該businessService方法時(shí),引入切入點(diǎn)

    ?????????? expression="com.xyz.myapp.SystemArchitecture.businessService()"/>

    </aop:config>

    3.完整的配置

    <aop:config>

    <aop:aspect id="myAspect" ref="aBean">

    <aop:pointcut id="businessService"

    ??????? expression="execution(* com.xyz.myapp.service..(..))"/>

    ?? …

    </aop:aspect>

    <aop:config>

    ?

    5-4 Advice應(yīng)用(配置)(上)

    1.前置通知Before advice

    聲明方式:

    <aop:aspect id="beforeExample" ref="aBean">

    ????? <aop:before

    ?????????? pointcut-ref="dataAccessOperation"?? //聲明參考切入點(diǎn)dataAccessOperation的聲明

    ?????????? method="doAccessCheck"/> //調(diào)用aBean的doAccessCheck方法

    ????? …

    </aop:aspect>

    <aop:aspect id="beforeExample" ref="aBean">

    ????? <aop:before

    ?????????? pointcut ="execution(* com.xyz.myapp.dao..(..))"????? //直接進(jìn)行聲明

    ?????????? method="doAccessCheck"/>

    ????? …

    </aop:aspect>

    2.返回后通知After returning advice

    聲明方式:

    <aop:aspect id="afterReturningExample" ref="aBean">

    ????? <aop: after-returning

    ?????????? pointcut-ref ="dataAccessOperation"

    ?????????? //returning="retVal" //可以使用returning屬性來(lái)限制返回值

    ?????????? method="doAccessCheck"/>

    ????? …

    </aop:aspect>

    3.返回異常后通知After throwing advice

    聲明方式:

    <aop:aspect id="afterThrowingExample" ref="aBean">

    ????? <aop: after-throwing

    ?????????? pointcut-ref ="dataAccessOperation"

    ?????????? //throwing="dataAccessEx"?? //可以使用throwing屬性來(lái)指定可被傳遞的異常的參數(shù)名稱

    ?????????? method="doRecoverActions"/>

    ????? …

    </aop:aspect>

    4.后通知After(finally) advice

    聲明方式:

    <aop:aspect id="afterFinallyExample" ref="aBean">

    ????? <aop: after

    ?????????? pointcut-ref ="dataAccessOperation"

    ?????????? method="doReleaseLock"/>

    ????? …

    </aop:aspect>

    ?

    5-5 Advice應(yīng)用(配置)(下)

    1.環(huán)繞通知Around Advice

    (1)通知方法的第一個(gè)參數(shù)必須是ProceedingJoinPoint類型

    (2)聲明方式

    <aop:aspect id="aroundExample" ref="aBean">

    ????? <aop: around

    ?????????? pointcut-ref ="businessService"

    ?????????? method="doBasicProfiling"/>

    ????? …

    </aop:aspect>

    (3)使用方式

    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {

    ????? //執(zhí)行業(yè)務(wù)方法前,可以有方法

    ????? Object retVal = pjp.proceed();??? //執(zhí)行業(yè)務(wù)方法

    ????? //執(zhí)行業(yè)務(wù)方法后,可以有方法

    ????? return retVal;

    }

    2.advice的參數(shù)

    通過(guò)在xml配置,可以將實(shí)現(xiàn)類的參數(shù)傳給環(huán)繞通知方法的參數(shù),進(jìn)而來(lái)使用

    接口:

    public interface FooService {

    ????? Foo getFoo(String fooName, int age);

    }

    實(shí)現(xiàn)類:

    public class DefaultFooService implements FooService {

    ????? public Foo getFoo(String name, int age) {

    ?????????? return new Foo(name, age);

    }

    }

    配置:

    <bean id="fooService" class="x.y.service.DefaultFooService"/>

    <bean id="profiler" class="x.y.SimpleProfiler"/>

    <aop:config>

    <aop:aspect ref="profiler">

    <aop:pointcut id="theExecutionOfSomeFooServiceMethod"

    ??????? expression="execution(* x.y.service.FooService.getFoo(String, int)) and args(name, age)" />

    ?? <aop:around pointcut-ref=" theExecutionOfSomeFooServiceMethod"

    ??????? method="profile"/>

    </aop:aspect>

    <aop:config>

    環(huán)繞通知:

    public calss SimpleProfiler {

    ????? public Object profile(ProceedingJoinPoint call, String name, int age) throws Throwable {

    ?????????? StopWatch clock = new StopWatch("Profiling for" + name + " and " + age + "");

    ?????????? try {

    ???????????????? clock.start(call.toShortString());

    ???????????????? return call.proceed();

    }finally {

    ????? clock.stop();

    ????? System.out.println(clock.prettyPrint());

    }

    }

    }

    ?

    5-6 Introductions(配置)

    1.簡(jiǎn)介允許一個(gè)切面來(lái)聲明一個(gè)實(shí)現(xiàn)指定接口的通知對(duì)象(即一個(gè)聲明了通知的切面,該通知實(shí)現(xiàn)了指定接口),并且提供了一個(gè)接口實(shí)現(xiàn)類來(lái)代表這些對(duì)象

    2.它由<aop:aspect>中的<aop:declare-parents>元素聲明,該元素用于聲明所匹配的類型擁有一個(gè)新的parent(因此得名)

    3.配置

    <aop:aspect id="usageTrackerAspect" ref="usageTracking">

    ????? <aop:declare-parents???? //聲明一個(gè)通知對(duì)象

    ?????????? types-matching="com.xyz.myapp.service.*(+)"?? //匹配該包下的所有類的方法

    ?????????? implement-interface="com.xyz.myapp.service.tracking.UsageTracked" //該通知對(duì)象實(shí)現(xiàn)了指定接口

    ?????????? default-impl="com.xyz.myapp.service.tracking.DefaultUsageTracked"/>???? //提供了接口實(shí)現(xiàn)類

    ????? <aop:before

    ?????????? pointcut="com.xyz.myapp.SystemArchitecture.businessService() and this(usageTracked)"

    ???????????????? method="recordUsage"/>

    </aop:aspect>

    當(dāng)匹配到符合的service的類時(shí),會(huì)為它賦予一個(gè)新的parent——UsageTracked,這樣在使用時(shí),可以對(duì)類(以新的父類接口)進(jìn)行強(qiáng)轉(zhuǎn),然后可以調(diào)用接口的方法(實(shí)現(xiàn)是指定的實(shí)現(xiàn)類的實(shí)現(xiàn))

    4.使用

    public void recordUsage(UsageTracked usageTracked) {

    ????? usageTracked.incrementUseCount();

    }

    ?

    UsageTracked usageTracked =(UsageTracked) context.getBean("myService");??

    5.所有基于配置文件(schema-defined)的aspents,只支持singleton model

    ?

    5-7 Advisors

    1.advisor就像一個(gè)小的自包含的方面,只有一個(gè)advice

    2.切面自身通過(guò)一個(gè)bean表示,并且必須實(shí)現(xiàn)某個(gè)advice接口,同時(shí),advisor也可以很好地利用AspectJ的切入點(diǎn)表達(dá)式

    3.Spring通過(guò)配置文件中的<aop:advisor>元素支持advisor。實(shí)際使用中,大多數(shù)情況下它會(huì)和transactional advice(事務(wù)相關(guān)的advice)配合使用

    4.為了定義一個(gè)advisor的優(yōu)先級(jí)以便讓advice可以有序,可以使用order屬性來(lái)定義advisor的順序

    5.例子

    <aop:config>

    ????? <aop:pointcut id="businessService"

    ?????????? expression="execution(* com.xyz.myapp.service..(..))"/>

    ????? <aop:advisor

    ?????????? pointcut-ref="businessService"

    ?????????? advice-ref="tx-advice"/>

    </aop:config>

    ?

    <tx:advice id="tx-advice">?? //事務(wù)相關(guān)

    ????? <tx:attributes>

    ?????????? <tx:method name="*" propagation="REQUIRED"/>

    ????? </tx"attributes>

    </tx:advice>

    ?

    第六章 Spring AOPAPI介紹(了解,常用的還是在xml中進(jìn)行配置)

    6-1 Spring AOP APIPointcut、advice概念及應(yīng)用

    1.Pointcut

    2.Before advice

    3.Throws advice

    4.After Returning advice

    5.Interception around advice

    6.Introduction advice

    7.Advisor

    ?

    6-2 ProxyFactoryBean及相關(guān)內(nèi)容(上)

    1.創(chuàng)建Spring AOP代理的基本方法是使用org.springframework.aop.framework.ProxyFactoryBean

    2.(即通過(guò)引入中間層)這可以完全控制切入點(diǎn)和通知(advice)以及他們的順序

    3.假如定義了一個(gè)bean id為foo的ProxyFactoryBean,那么引用foo對(duì)象時(shí),看到的將不是ProxyFactoryBean本身的實(shí)例,而是ProxyFactoryBean實(shí)現(xiàn)里getObject()方法創(chuàng)建的對(duì)象,getObject方法將創(chuàng)建一個(gè)AOP代理來(lái)包裝一個(gè)目標(biāo)對(duì)象。通過(guò)這種方式來(lái)達(dá)到代理的目的

    4.

    (1)使用ProxyFactoryBean或者其它IoC相關(guān)類來(lái)創(chuàng)建AOP代理的最重要好處是通知和切入點(diǎn)也可以由IoC來(lái)管理

    (2)如果被代理類沒(méi)有實(shí)現(xiàn)任何借口,則使用CGLIB代理,否則使用JDK代理

    (3)通過(guò)設(shè)置proxyTargetClass為true,可強(qiáng)制使用CGLIB

    (4)如果目標(biāo)類實(shí)現(xiàn)了一個(gè)(或者多個(gè))接口,那么創(chuàng)建代理的類型將依賴ProxyFactoryBean的配置

    (5)如果ProxyFactoryBean的proxyInterfaces屬性被設(shè)置為一個(gè)或多個(gè)全限定接口名,基于JDK的代理將被創(chuàng)建

    (6)如果ProxyFactoryBean的proxyInterfaces屬性沒(méi)有被設(shè)置,但是目標(biāo)類實(shí)現(xiàn)了一個(gè)(或更多)接口,那么ProxyFactoryBean將自動(dòng)檢測(cè)這個(gè)類已將實(shí)現(xiàn)了至少一個(gè)接口,創(chuàng)建一個(gè)基于JDK的代理

    5.創(chuàng)建基于接口的代理——代碼

    <bean id="personTarget" class="com.mycompany.PersonImpl">

    ????? <property name="name" value="Tony"/>

    ????? <preperty name="age" value="51"/>

    </bean>

    ?

    <bean id="myAdvisor" class="com.mycompany.MyAdvisor">

    ????? <property name="someProperty" value="Custom string property value"/>

    </bean>

    ?

    <bean id="debugInterceptor" class="org.spring.aop.interceptor.DebugInterceptor">

    </bean>

    ?

    //不是直接把Person類賦給person,而是中間有一個(gè)代理層

    <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">

    ????? <property name="proxyInterfaces" value="com.mycompany.Person"/>

    ?????

    ????? <property name="target" ref="personTarget"/>

    ????? <property name="interceptorNames">

    ?????????? <list>

    ???????????????? <value>myAdvisor</vlaue>

    ???????????????? <value>debugInterceptor</value>

    ?????????? </list>

    ????? </property>

    </bean>

    ?

    //其它bean調(diào)用時(shí)

    <bean id="personUser" class="com.mycompany.PersonUser">

    ????? <property name="person"><ref bean="person"/></property>

    </bean>

    6.使用匿名內(nèi)部bean來(lái)隱藏目標(biāo)和代理之間的關(guān)系(即不用reference,直接在內(nèi)部定義bean)(推薦使用)

    <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">

    ????? <property name="proxyInterfaces" value="com.mycompany.Person"/>

    ?????

    ????? <property name="target"

    <bean class="com.mycompany.PersonImpl">

    ?? <property name="name" value="Tony"/>

    ?? <preperty name="age" value="51"/>

    </bean>

    ????? <property name="interceptorNames">

    ?????????? <list>

    ???????????????? <value>myAdvisor</vlaue>

    ???????????????? <value>debugInterceptor</value>

    ?????????? </list>

    ????? </property>

    </bean>

    ?

    6-3 ProxyFactoryBean及相關(guān)內(nèi)容(下)

    1.Proxying classes(Proxy類)

    (1)前面的例子中如果沒(méi)有Person接口,則Spring會(huì)使用CGLIB代理,而不是JDK動(dòng)態(tài)代理

    (2)如果想,可以強(qiáng)制在任何情況下使用CGLIB,即使有接口

    (3)CGLIB代理的工作原理是在運(yùn)行時(shí)生成目標(biāo)類的子類,Spring配置這個(gè)生成的子類委托方法調(diào)用到原來(lái)的目標(biāo)

    (4)子類是用來(lái)實(shí)現(xiàn)Decorator模式,織入通知

    (5)CGLIB的代理對(duì)用戶是透明的,需要注意:

    1°final不能被通知,因?yàn)樗鼈儾荒鼙桓采w

    2°不需要把CGLIB添加到classpath中,在Spring3.2中,CGLIB被重新包裝并包含在Spring核心的JAR(即基于CGLIB的AOP就像JDK動(dòng)態(tài)代理一樣“開(kāi)箱即用”)

    2.使用global advisors

    用*做通配,匹配所有攔截器加入通知鏈(即實(shí)現(xiàn)Interceptor接口的),例:

    <list>

    ????? <value>mooc*</vlaue>

    </list>

    3.簡(jiǎn)化的proxy定義

    使用父子bean定義,以及內(nèi)部bean定義,可能回帶來(lái)更清潔和更簡(jiǎn)潔的代理定義(抽象屬性標(biāo)記父bean定義為抽象的這樣它不能被實(shí)例化)

    4.使用ProxyFactory

    (1)好處:使用Spring AOP而不必依賴于Spring IoC

    ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);

    factory.addAdvice(myMethodInterceptor);

    factory.addAdvisor(myAdvisor);

    MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();

    (2)大多數(shù)情況下最佳實(shí)踐是用IoC容器創(chuàng)建AOP代理

    (3)雖然可以硬編碼方式實(shí)現(xiàn),但是Spring推薦使用配置或注解方式實(shí)現(xiàn)

    5.使用"auto-proxy"

    (1)Spring也允許使用“自動(dòng)代理”的bean定義,它可以自動(dòng)代理選定的bean,這是建立在Spring的"bean psot processor"功能基礎(chǔ)上的(這個(gè)功能在加載bean的時(shí)候就可以修改)

    (2)通過(guò)BeanNameAutoProxyCreator實(shí)現(xiàn)

    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

    ????? <property name="beanNames" value="jdk*,onlyJdk"/>??? //自動(dòng)代理jdk開(kāi)頭的或onlyJdk的所有bean

    ????? <property name="interceptorNames">

    ?????????? <list>

    ???????????????? <value>myInterceptor</value>

    ?????????? <list>

    ????? <property>

    </bean>

    (3)通過(guò)DefaultAdvisorAutoProxyCreator實(shí)現(xiàn),則當(dāng)前IoC容器中自動(dòng)應(yīng)用來(lái)達(dá)到創(chuàng)建代理的效果,不用顯示聲明引用advisor的bean定義

    ?

    第七章 Spring對(duì)AspectJ的支持

    7-1 AspectJ介紹及Pointcut注解應(yīng)用

    1.AspectJ

    (1)@AspectJ的風(fēng)格類似純java注解的普通java類

    (2)Spring可以使用AspectJ來(lái)做切入點(diǎn)解析

    (3)AOP的運(yùn)行時(shí)仍舊是純的Spring AOP,對(duì)AspectJ的編譯器或者織入無(wú)依賴性

    2.Spring中配置@AspectJ

    (1)對(duì)@AspectJ支持可以使用xml或java風(fēng)格的配置

    (2)確保AspectJ的aspectjweaver.jar庫(kù)包含在應(yīng)用程序(版本1.6.8或更高版本)的classpath中

    1°注解

    @Configuration

    @EnableAspectJAutoProxy

    public class AppConfig {

    }

    2°xml配置

    <aop:aspectj-autoproxy/>

    3.@Aspect注解

    (1)@AspectJ切面使用@Aspect注解配置,擁有@Aspect的任何bean將被Spring自動(dòng)識(shí)別并應(yīng)用

    (2)用@Aspect注解的類可以有方法和字段,它們也可能包括切入點(diǎn)(pointcut),通知(Advice)和引入(introduction)聲明

    (3)@Aspect注解是不能夠通過(guò)類路徑自動(dòng)檢測(cè)發(fā)現(xiàn)的,所以@Aspect需要配合使用@Component注釋或者在xml配置bean,如:

    <bean id="myAspect" class="org.xyz.NotVeryUserfulAspect">

    ????? //配置aspect的屬性

    </bean>

    ?

    @Aspect

    public class NotVeryUserfulAspect {

    }

    @Component

    @Aspect

    public class NotVeryUserfulAspect {

    }

    (4)一個(gè)類中的@Aspect注解將標(biāo)識(shí)它為一個(gè)切面,并且將自己從自動(dòng)代理中排除(不會(huì)代理自己)

    4.如何定義切入點(diǎn)pointcut

    (1)一個(gè)切入點(diǎn)通過(guò)一個(gè)普通的方法定義來(lái)提供,并且切入點(diǎn)表達(dá)式使用@Pointcut注解,方法返回類型必須為void

    如:

    @Pointcut("execution(* transfer(..))")

    private void anyOldTransfer() {}

    定義一個(gè)名為anyOldTransfer的方法(即一個(gè)切入點(diǎn)),這個(gè)切入點(diǎn)將匹配任何名為"transfer"的方法

    5.切入點(diǎn)支持哪些定義方式(哪些點(diǎn)可以定義)

    execution:匹配方法執(zhí)行的連接點(diǎn)

    within:限定匹配特定類型的連接點(diǎn)

    this:匹配特定連接點(diǎn)的bean引用是指定類型的實(shí)例的限制

    target:限定匹配特定連接點(diǎn)的目標(biāo)對(duì)象時(shí)指定類型的實(shí)例

    args:限定匹配特定連接點(diǎn)的參數(shù)是指定類型的實(shí)例

    @target:限定匹配特定連接點(diǎn)的類執(zhí)行對(duì)象的具有給定類型的注解

    @args:限定匹配特定連接點(diǎn)實(shí)際傳入?yún)?shù)的類型具有給定類型的注解

    @within:限定匹配到內(nèi)具有給定的注釋類型的連接點(diǎn)

    @annotation:限定匹配特定連接點(diǎn)的主體具有給定的注解

    6.組合pointcut

    (1)切入點(diǎn)表達(dá)式可以通過(guò)&&、||和!進(jìn)行組合,也可以通過(guò)名字引入切入點(diǎn)表達(dá)式

    (2)通過(guò)組合,可以建立更為復(fù)雜的切入點(diǎn)表達(dá)式,如:

    @Pointcut("execution(public * (..))")

    private void anyPublicOperation() {}

    ?

    @Pointcut("within(com.xyz.comeapp.trading..)")

    private void inTrading() {}

    ?

    @Pointcut("anyPublicOperation() && inTrading()")

    private void tradingOperation() {}

    7.如何定義良好的pointcuts

    (1)AspectJ是編譯期的AOP

    (2)檢查代碼并匹配連接點(diǎn)與切入點(diǎn)的代價(jià)是昂貴的

    (3)一個(gè)好的切入點(diǎn)應(yīng)該包含以下幾點(diǎn)

    1°選擇特定類型的切入點(diǎn),如:execution、get、set、call、handeler

    2°確定連接點(diǎn)范圍,如:within、withincode

    3°匹配上下文信息,如:this、target、@annotation

    ?

    7-2 Advice定義及實(shí)例

    1.Before advice

    (1)例子

    1°直接定義execution表達(dá)式

    @Component

    @Aspect

    public class MoocAspect {

    ????? @Before("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))*)

    ????? public void before() {

    //…

    }

    }

    在執(zhí)行com.imooc.aop.aspectj包下以Biz結(jié)尾的類的所有方法時(shí)匹配Advice

    2°引用一個(gè)已經(jīng)存在的pointcut

    @Component

    @Aspect

    public class MoocAspect {

    ????? @Pointcut("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")

    public void pointcut() {}

    ?

    @Before("execution(*pointcut()")

    ????? public void before() {

    //…

    }

    }

    2.After returning advice

    (1)有時(shí)候需要在通知體內(nèi)得到返回的實(shí)際值,可以使用@AfterReturning綁定返回值的類型

    @AfterReturning(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", returning="retVal")

    public void do AccessCheck(Object retVal) {

    ????? //…

    }

    將@AfterReturning注解中的返回值在下面的方法中聲明,不確定返回值的類型則為Object

    3.After throwing advice

    4.After(finally) advice

    (1)最終通知必須準(zhǔn)備處理正常和異常兩種返回情況,它通常用于釋放資源

    5.Around advice

    (1)環(huán)繞通知使用@Around注解來(lái)聲明,通知方法的第一個(gè)參數(shù)必須是ProceedingJoinPoint類型

    (2)在通知內(nèi)部調(diào)用ProceedingJoinPoint的proceed()方法會(huì)導(dǎo)致執(zhí)行真正的方法,傳入一個(gè)Object[]對(duì)象,數(shù)組中的值將被作為參數(shù)傳遞給方法

    ?

    7-3 Advice擴(kuò)展

    1.給advice傳遞參數(shù)

    2.Advice的參數(shù)及泛型

    3.Advice參數(shù)名稱

    (1)通知和切入點(diǎn)注解有一個(gè)額外的"argNames"屬性,它可以用來(lái)指定所注解的方法的參數(shù)名,如:

    @Before(vlaue="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)", argNames="bean,auditable")

    public void audit(Object bean, Auditable auditable) {

    AuditCode code = auditable.value();

    // … use code and bean

    }

    (2)如果第一個(gè)參數(shù)是JointPoint、ProceedingJoinPoint、JoinPoint.StaticPart,那么可以忽略它

    4.Introductions

    (1)允許一個(gè)切面聲明一個(gè)通知對(duì)象實(shí)現(xiàn)指定接口,并且提供了一個(gè)接口實(shí)現(xiàn)類來(lái)代表這些對(duì)象

    (2)AspectJ中使用@DeclareParents來(lái)對(duì)introduction進(jìn)行注解,這個(gè)注解用來(lái)定義匹配的類型擁有一個(gè)新的parent

    5.切面實(shí)例化模型

    (1)這是一個(gè)高級(jí)主題

    (2)"perthis"切面通過(guò)指定@Aspect注解perthis子句實(shí)現(xiàn)

    (3)每個(gè)獨(dú)立的service對(duì)象執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)切面實(shí)例

    (4)service對(duì)象的每個(gè)方法在第一次執(zhí)行的時(shí)候創(chuàng)建切面實(shí)例,切面在service對(duì)象失效的同時(shí)失效

    @Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")

    public class MyAspect {

    ????? private int someState;

    ?

    ????? @Before(com.xyz.myapp.SystemArchitecture.businessService())??

    ????? public void recordServiceUsage() {

    ?????????? //…

    }

    }


    查看全部
    0 采集 收起 來(lái)源:Advice擴(kuò)展

    2019-08-21

舉報(bào)

0/150
提交
取消
課程須知
Java的高級(jí)課程,適合對(duì)Java基礎(chǔ)知識(shí)應(yīng)用自如,并熟悉MVC架構(gòu)的小伙伴們。如果想成為一名Java工程師,這門課程是一定要學(xué)噠。
老師告訴你能學(xué)到什么?
掌握依賴注入、IOC和AOP的概念,并能進(jìn)行簡(jiǎn)單應(yīng)用。

微信掃碼,參與3人拼團(tuán)

微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

友情提示:

您好,此課程屬于遷移課程,您已購(gòu)買該課程,無(wú)需重復(fù)購(gòu)買,感謝您對(duì)慕課網(wǎng)的支持!