程序員之Spring

1. Spring事務(wù)

spring的事務(wù)實(shí)現(xiàn)原理
Spring事務(wù)將connection放入到當(dāng)前線程的threadlocal中,spring中使用ThreadLocal來設(shè)計(jì)TransactionSynchronizationManager類,實(shí)現(xiàn)了事務(wù)管理與數(shù)據(jù)訪問服務(wù)的解耦,同時(shí)也保證了多線程環(huán)境下connection的線程安全問題。

2.Spring bean的作用域

類別 說明
singletone:單例 在spring中僅存在一個(gè)Bean實(shí)例,Spring默認(rèn)為單例模式。
prototype:原型模式 每次通過Spring容器獲取prototype定義的bean時(shí),容器都將創(chuàng)建一個(gè)新的Bean實(shí)例,每個(gè)Bean實(shí)例都有自己的屬性和狀態(tài)。
request:請求模式 在一次Http請求中,容器會(huì)返回該Bean的同一實(shí)例,而對不同的Http請求則會(huì)產(chǎn)生新的Bean,而且該bean僅在當(dāng)前Http Request內(nèi)有效。
session:會(huì)話模式 在一次Http Session中,容器會(huì)返回該Bean的同一實(shí)例。而對不同的Session請求則會(huì)創(chuàng)建新的實(shí)例,該bean實(shí)例僅在當(dāng)前Session內(nèi)有效。
global Session:全局會(huì)話模式 在一個(gè)全局的Http Session中,容器會(huì)返回該Bean的同一個(gè)實(shí)例,僅在使用portlet context時(shí)有效。

2. Spring AOP

AOP(Aspect Oriented Programing)指面向切面編程,是通過預(yù)編譯和運(yùn)行時(shí)動(dòng)態(tài)代理實(shí)現(xiàn)的一種技術(shù)。

2.1 AOP 相關(guān)概念

1.連接點(diǎn):join point

指Java程序中的具有邊界性質(zhì)的特定位置,如類初始化之前,類初始化之后,方法調(diào)用前和方法調(diào)用后等。目前Spring僅支持類方法這樣的join point,可以在方法前,方法后這樣的連接點(diǎn)織入(weaving)增強(qiáng)(advice)。

2.切點(diǎn):point cut

AOP把類方法作為查詢條件,通過point cut找到連接點(diǎn)(join point),即讓切點(diǎn)來篩選連接點(diǎn),如目標(biāo)類有5個(gè)方法, 程序只想讓3個(gè)方法實(shí)現(xiàn)增強(qiáng),剩余的2個(gè)不需要增強(qiáng),那個(gè)就通過point cut從5個(gè)方法中,篩選出需要增強(qiáng)的3個(gè)方法。

3.通知:advice

advice是織入到目標(biāo)類方法(即join point)的程序代碼塊,并且制定要織入的連接點(diǎn)的方位(方法前,方法后等),advice主要有AfterAdvice,BeforeAdvice,ThrowAdvice,MethodInterceptor和AfterReturningAdvice等。

4.目標(biāo)對象:Target

advice的增強(qiáng)代碼織入的目標(biāo)類。

5.引入:Introduction

Introduction為類添加屬性或者方法,這樣是一些類在沒有實(shí)現(xiàn)某些接口的情況下,動(dòng)態(tài)的添加該接口的實(shí)現(xiàn)。

6.織入:weaving

織入是指將advice添加到目標(biāo)類方法(即連接點(diǎn))上的過程,Spring采用動(dòng)態(tài)代理織入,AspectJ采用編譯器期間和類加載期間織入。

7.代理:proxy

目標(biāo)類被織入advice后,形成一個(gè)新的代理類,該代理類同時(shí)具有目標(biāo)類和advice的功能。

8.切面:Aspect

切面包含了point cut和advice組成,point cut指定了在什么地方干(指定增強(qiáng)的目標(biāo)類方法),advice指定了干什么(增強(qiáng)代碼塊)和什么時(shí)候(before or after)干。

2.2 Java代理模式

可參考如下文章:
1.設(shè)計(jì)模式(4)-代理模式
2.Java代理(Proxy)模式

這里不再贅述。

2.3 AOP 實(shí)現(xiàn)原理

AOP目前有兩種實(shí)現(xiàn)方式:
1.靜態(tài)代理:靜態(tài)代理可以實(shí)現(xiàn)編譯時(shí)增強(qiáng),即在程序編譯階段就生成AOP代理對象。AspectJ就是使用了靜態(tài)代理的方式;
2.動(dòng)態(tài)代理:動(dòng)態(tài)代理可以實(shí)現(xiàn)運(yùn)行時(shí)增強(qiáng),即在程序運(yùn)行時(shí)使用JDK動(dòng)態(tài)代理或者Cglib代理(Code Generation Library,即代碼生成包,所以也可以稱為動(dòng)態(tài)字節(jié)碼增強(qiáng)代理
),臨時(shí)生成AOP代理類。Spring AOP就是使用的動(dòng)態(tài)代理。

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

JDK動(dòng)態(tài)代理是針對接口的代理,只有接口方法才能夠被代理,主要使用的JDK的rt.jar中的java.lang.reflect.Proxy代理類和java.lang.reflect.InvocationHandler調(diào)用程序接口。Proxy代理類內(nèi)部有一個(gè)屬性InvocationHandler h

package java.lang.reflect;
public class Proxy implements Serializable {
     protected InvocationHandler h;

    protected Proxy(InvocationHandler var1) {
        Objects.requireNonNull(var1);
        this.h = var1;
    }

    @CallerSensitive
    public static Class<?> getProxyClass(ClassLoader var0, Class... var1) throws IllegalArgumentException {
       ...
       ...     
}

    @CallerSensitive
    public static Object newProxyInstance(ClassLoader classLoader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
       ...
       ...        
    }
}

其中:
ClassLoader classLoader:指類加載器;
Class<?>[] interfaces:獲得的全部接口;
InvocationHandler h: 得到InvocationHandler接口的子類實(shí)例。

InvocationHandler.java

public interface InvocationHandler {
    /**

  */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

其中:
Object proxy:指被代理的對象;
Method method:要調(diào)用的proxy的方法;
Object[] args: 指調(diào)用target目標(biāo)類的方法的參數(shù)。

JDK動(dòng)態(tài)代理的主要思路:
將InvocationHandler接口的子類封裝成一個(gè)proxy的最終操作類,替換到target目標(biāo)類,然后通過invoke(Object proxy, Method method, Object[] args)方法執(zhí)行對target目標(biāo)類的增強(qiáng)代碼塊和target目標(biāo)類的方法。JDK動(dòng)態(tài)代理只是在創(chuàng)建動(dòng)態(tài)代理時(shí),將被代理接口和InvocationHandler的實(shí)現(xiàn)類進(jìn)行關(guān)聯(lián),當(dāng)proxy執(zhí)行被代理的target的方法時(shí),通過InvocationHandler的invoke方法來執(zhí)行。

JDK動(dòng)態(tài)代理的缺點(diǎn):
JDK動(dòng)態(tài)代理的Proxy類的 public static Object newProxyInstance(ClassLoader classLoader, Class<?>[] interfaces, InvocationHandler h)方法中,interfaces限制了target必須是接口或者接口的實(shí)現(xiàn)。如果類沒有實(shí)現(xiàn)接口,那么只能使用Cglib代理了。

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

Cglib動(dòng)態(tài)代理采用字節(jié)碼技術(shù),為target目標(biāo)類創(chuàng)建一個(gè)子類,Override需要被代理的方法,并在子類中采用方法攔截的技術(shù),攔截所有父類的方法調(diào)用,然后織入advice代碼塊。理解Cglib代理的原理后,也就明白target目標(biāo)類不能是final類,而且被代理的方法不能是private,final和static的。

Cglib動(dòng)態(tài)代理主要用到了cglib-***.jar包中的net.sf.cglib.proxy.MethodInterceptor接口和net.sf.cglib.proxy.Enhancer接口,其中MethodInterceptor繼承了net.sf.cglib.proxy.Callback接口,當(dāng)調(diào)用代理對象方法的時(shí)候會(huì)交給callback對象的來處理。

MethodInterceptor接口:

package net.sf.cglib.proxy;

import java.lang.reflect.Method;

public interface MethodInterceptor extends Callback {
    Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy ) throws Throwable;
}

其中:
Object proxy:指子類代理對象;
Method method:要調(diào)用的方法的反射對象;
Object[] args:指傳遞給method的參數(shù);
MethodProxy methodProxy:cglib生成的用來代替method對象的。

Cglib的核心是實(shí)現(xiàn)MethodInterceptor接口,使用intercept()方法進(jìn)行面向切面的處理,調(diào)用相應(yīng)的增強(qiáng)advice。

2. Spring IOC

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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