成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

徒手?jǐn)]框架--實(shí)現(xiàn)Aop

weij / 3518人閱讀

摘要:只實(shí)現(xiàn)了基于方法的攔截器。實(shí)現(xiàn)了一個(gè)遞歸的調(diào)用,直到執(zhí)行完所有的攔截器。目標(biāo)對(duì)象攔截器列表這個(gè)就是我們框架能夠理解的數(shù)據(jù)結(jié)構(gòu),這個(gè)時(shí)候問題就變成了對(duì)于哪個(gè)目標(biāo),增加哪些攔截器。

原文地址:犀利豆的博客

上一講我們講解了Spring 的 IoC 實(shí)現(xiàn)。大家可以去我的博客查看點(diǎn)擊鏈接,這一講我們繼續(xù)說說 Spring 的另外一個(gè)重要特性 AOP。之前在看過的大部分教程,對(duì)于Spring Aop的實(shí)現(xiàn)講解的都不太透徹,大部分文章介紹了Spring Aop的底層技術(shù)使用了動(dòng)態(tài)代理,至于Spring Aop的具體實(shí)現(xiàn)都語焉不詳。這類文章看以后以后,我腦子里浮現(xiàn)的就是這樣一個(gè)畫面:

我的想法就是,帶領(lǐng)大家,首先梳理 Spring Aop的實(shí)現(xiàn),然后屏蔽細(xì)節(jié),自己實(shí)現(xiàn)一個(gè)Aop框架。加深對(duì)Spring Aop的理解。在了解上圖1-4步驟的同時(shí),補(bǔ)充 4 到 5 步驟之間的其他細(xì)節(jié)。

讀完這篇文章你將會(huì)了解:

Aop是什么?

為什么要使用Aop?

Spirng 實(shí)現(xiàn)Aop的思路是什么

自己根據(jù)Spring 思想實(shí)現(xiàn)一個(gè) Aop框架

Aop 是什么?

面向切面的程序設(shè)計(jì)(aspect-oriented programming,AOP)。通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能統(tǒng)一維護(hù)的一種技術(shù)。

為什么需要使用Aop?

面向切面編程,實(shí)際上就是通過預(yù)編譯或者動(dòng)態(tài)代理技術(shù)在不修改源代碼的情況下給原來的程序統(tǒng)一添加功能的一種技術(shù)。我們看幾個(gè)關(guān)鍵詞,第一個(gè)是“動(dòng)態(tài)代理技術(shù)”,這個(gè)就是Spring Aop實(shí)現(xiàn)底層技術(shù)。第二個(gè)“不修改源代碼”,這個(gè)就是Aop最關(guān)鍵的地方,也就是我們平時(shí)所說的非入侵性。。第三個(gè)“添加功能”,不改變?cè)械脑创a,為程序添加功能。

舉個(gè)例子:如果某天你需要統(tǒng)計(jì)若干方法的執(zhí)行時(shí)間,如果不是用Aop技術(shù),你要做的就是為每一個(gè)方法開始的時(shí)候獲取一個(gè)開始時(shí)間,在方法結(jié)束的時(shí)候獲取結(jié)束時(shí)間。二者之差就是方法的執(zhí)行時(shí)間。如果對(duì)每一個(gè)需要統(tǒng)計(jì)的方法都做如上的操作,那代碼簡直就是災(zāi)難。如果我們使用Aop技術(shù),在不修改代碼的情況下,添加一個(gè)統(tǒng)計(jì)方法執(zhí)行時(shí)間的切面。代碼就變得十分優(yōu)雅。具體這個(gè)切面怎么實(shí)現(xiàn)?看完下面的文章你一定就會(huì)知道。

Spring Aop 是怎么實(shí)現(xiàn)的?

所謂:

計(jì)算機(jī)程序 = 數(shù)據(jù)結(jié)構(gòu) + 算法

在閱讀過Spring源碼之后,你就會(huì)對(duì)這個(gè)說法理解更深入了。

Spring Aop實(shí)現(xiàn)的代碼非常非常的繞。也就是說 Spring 為了靈活做了非常深層次的抽象。同時(shí) Spring為了兼容 @AspectJ 的Aop協(xié)議,使用了很多 Adapter (適配器)模式又進(jìn)一步的增加了代碼的復(fù)雜程度。
Spring 的 Aop 實(shí)現(xiàn)主要以下幾個(gè)步驟:

初始化 Aop 容器。

讀取配置文件。

將配置文件裝換為 Aop 能夠識(shí)別的數(shù)據(jù)結(jié)構(gòu) -- Advisor。這里展開講一講這個(gè)advisor。Advisor對(duì)象中包又含了兩個(gè)重要的數(shù)據(jù)結(jié)構(gòu),一個(gè)是 Advice,一個(gè)是 Pointcut。Advice的作用就是描述一個(gè)切面的行為,pointcut描述的是切面的位置。兩個(gè)數(shù)據(jù)結(jié)的組合就是”在哪里,干什么“。這樣 Advisor 就包含了”在哪里干什么“的信息,就能夠全面的描述切面了。

Spring 將這個(gè) Advisor 轉(zhuǎn)換成自己能夠識(shí)別的數(shù)據(jù)結(jié)構(gòu) -- AdvicedSupport。Spirng 動(dòng)態(tài)的將這些方法攔截器織入到對(duì)應(yīng)的方法。

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

提供調(diào)用,在使用的時(shí)候,調(diào)用方調(diào)用的就是代理方法。也就是已經(jīng)織入了增強(qiáng)方法的方法。

自己實(shí)現(xiàn)一個(gè) Aop 框架

同樣,我也是參考了Aop的設(shè)計(jì)。只實(shí)現(xiàn)了基于方法的攔截器。去除了很多的實(shí)現(xiàn)細(xì)節(jié)。

使用上一講的 IoC 框架管理對(duì)象。使用 Cglib 作為動(dòng)態(tài)代理的基礎(chǔ)類。使用 maven 管理 jar 包和 module。所以上一講的 IoC 框架會(huì)作為一個(gè) modules 引入項(xiàng)目。

下面我們就來實(shí)現(xiàn)我們的Aop 框架吧。

首先來看看代碼的基本結(jié)構(gòu)。

代碼結(jié)構(gòu)比上一講的 IoC 復(fù)雜不少。我們首先對(duì)包每個(gè)包都干了什么做一個(gè)簡單介紹。

invocation 描述的就是一個(gè)方法的調(diào)用。注意這里指的是“方法的調(diào)用”,而不是調(diào)用這個(gè)動(dòng)作。

interceptor 大家最熟悉的攔截器,攔截器攔截的目標(biāo)就是 invcation 包里面的調(diào)用。

advisor 這個(gè)包里的對(duì)象,都是用來描述切面的數(shù)據(jù)結(jié)構(gòu)。

adapter 這個(gè)包里面是一些適配器方法。對(duì)于"適配器"不了解的同學(xué)可以去看看"設(shè)計(jì)模式"里面的"適配模式"。他的作用就是將 advice 包里的對(duì)象適配為 interceptor

bean 描述我們 json 配置文件的對(duì)象。

core 我們框架的核心邏輯。

這個(gè)時(shí)候宏觀的看我們大概梳理出了一條路線, adaperadvisor 適配為 interceptor 去攔截 invoction。

下面我們從這個(gè)鏈條的最末端講起:

invcation

首先 MethodInvocation 作為所有方法調(diào)用的接口。要描述一個(gè)方法的調(diào)用包含三個(gè)方法,獲取方法本身getMethod,獲取方法的參數(shù)getArguments,還有執(zhí)行方法本身proceed()

public interface MethodInvocation {
    Method getMethod();
    Object[] getArguments();
    Object proceed() throws Throwable;
}

ProxyMethodInvocation 看名字就知道,是代理方法的調(diào)用,增加了一個(gè)獲取代理的方法。

public interface ProxyMethodInvocation extends MethodInvocation {
    Object getProxy();
}
interceptor

AopMethodInterceptor 是 Aop 容器所有攔截器都要實(shí)現(xiàn)的接口:

public interface AopMethodInterceptor {
    Object invoke(MethodInvocation mi) throws Throwable;
}

同時(shí)我們實(shí)現(xiàn)了兩種攔截器BeforeMethodAdviceInterceptorAfterRunningAdviceInterceptor,顧名思義前者就是在方法執(zhí)行以前攔截,后者就在方法運(yùn)行結(jié)束以后攔截:

public class BeforeMethodAdviceInterceptor implements AopMethodInterceptor {
    private BeforeMethodAdvice advice;
    public BeforeMethodAdviceInterceptor(BeforeMethodAdvice advice) {
        this.advice = advice;
    }
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        advice.before(mi.getMethod(),mi.getArguments(),mi);
        return mi.proceed();
    }
}
public class AfterRunningAdviceInterceptor implements AopMethodInterceptor {
    private AfterRunningAdvice advice;

    public AfterRunningAdviceInterceptor(AfterRunningAdvice advice) {
        this.advice = advice;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object returnVal = mi.proceed();
        advice.after(returnVal,mi.getMethod(),mi.getArguments(),mi);
        return returnVal;
    }
}

看了上面的代碼我們發(fā)現(xiàn),實(shí)際上 mi.proceed()才是執(zhí)行原有的方法。而advice我們上文就說過,是描述增強(qiáng)的方法”干什么“的數(shù)據(jù)結(jié)構(gòu),所以對(duì)于這個(gè)before攔截器,我們就把a(bǔ)dvice對(duì)應(yīng)的增強(qiáng)方法放在了真正執(zhí)行的方法前面。而對(duì)于after攔截器而言,就放在了真正執(zhí)行的方法后面。

這個(gè)時(shí)候我們過頭來看最關(guān)鍵的 ReflectioveMethodeInvocation

public class ReflectioveMethodeInvocation implements ProxyMethodInvocation {
    public ReflectioveMethodeInvocation(Object proxy, Object target, Method method, Object[] arguments, List interceptorList) {
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.arguments = arguments;
        this.interceptorList = interceptorList;
    }

    protected final Object proxy;

    protected final Object target;

    protected final Method method;

    protected Object[] arguments = new Object[0];

    //存儲(chǔ)所有的攔截器
    protected final List interceptorList;

    private int currentInterceptorIndex = -1;

    @Override
    public Object getProxy() {
        return proxy;
    }

    @Override
    public Method getMethod() {
        return method;
    }

    @Override
    public Object[] getArguments() {
        return arguments;
    }

    @Override
    public Object proceed() throws Throwable {

        //執(zhí)行完所有的攔截器后,執(zhí)行目標(biāo)方法
        if(currentInterceptorIndex == this.interceptorList.size() - 1) {
            return invokeOriginal();
        }

        //迭代的執(zhí)行攔截器。回顧上面的講解,我們實(shí)現(xiàn)的攔擊都會(huì)執(zhí)行 im.proceed() 實(shí)際上又會(huì)調(diào)用這個(gè)方法。實(shí)現(xiàn)了一個(gè)遞歸的調(diào)用,直到執(zhí)行完所有的攔截器。
        AopMethodInterceptor interceptor = interceptorList.get(++currentInterceptorIndex);
        return interceptor.invoke(this);

    }

    protected Object invokeOriginal() throws Throwable{
        return ReflectionUtils.invokeMethodUseReflection(target,method,arguments);
    }

}


在實(shí)際的運(yùn)用中,我們的方法很可能被多個(gè)方法的攔截器所增強(qiáng)。所以我們,使用了一個(gè)list來保存所有的攔截器。所以我們需要遞歸的去增加攔截器。當(dāng)處理完了所有的攔截器之后,才會(huì)真正調(diào)用調(diào)用被增強(qiáng)的方法。我們可以認(rèn)為,前文所述的動(dòng)態(tài)的織入代碼就發(fā)生在這里。

public class CglibMethodInvocation extends ReflectioveMethodeInvocation {

    private MethodProxy methodProxy;

    public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments, List interceptorList, MethodProxy methodProxy) {
        super(proxy, target, method, arguments, interceptorList);
        this.methodProxy = methodProxy;
    }

    @Override
    protected Object invokeOriginal() throws Throwable {
        return methodProxy.invoke(target,arguments);
    }
}

CglibMethodInvocation 只是重寫了 invokeOriginal 方法。使用代理類來調(diào)用被增強(qiáng)的方法。

advisor

這個(gè)包里面都是一些描述切面的數(shù)據(jù)結(jié)構(gòu),我們講解兩個(gè)重要的。

@Data
public class Advisor {
    //干什么
    private Advice advice;
    //在哪里
    private Pointcut pointcut;

}

如上文所說,advisor 描述了在哪里,干什么。

@Data
public class AdvisedSupport extends Advisor {
    //目標(biāo)對(duì)象
    private TargetSource targetSource;
    //攔截器列表
    private List list = new LinkedList<>();

    public void addAopMethodInterceptor(AopMethodInterceptor interceptor){
        list.add(interceptor);
    }

    public void addAopMethodInterceptors(List interceptors){
        list.addAll(interceptors);
    }

}

這個(gè)AdvisedSupport就是 我們Aop框架能夠理解的數(shù)據(jù)結(jié)構(gòu),這個(gè)時(shí)候問題就變成了--對(duì)于哪個(gè)目標(biāo),增加哪些攔截器。

core

有了上面的準(zhǔn)備,我們就開始講解核心邏輯了。

@Data
public class CglibAopProxy implements AopProxy{
    private AdvisedSupport advised;
    private Object[] constructorArgs;
    private Class[] constructorArgTypes;
    public CglibAopProxy(AdvisedSupport config){
        this.advised = config;
    }

    @Override
    public Object getProxy() {
        return getProxy(null);
    }
    @Override
    public Object getProxy(ClassLoader classLoader) {
        Class rootClass = advised.getTargetSource().getTagetClass();
        if(classLoader == null){
            classLoader = ClassUtils.getDefultClassLoader();
        }
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(rootClass.getSuperclass());
        //增加攔截器的核心方法
        Callback callbacks = getCallBack(advised);
        enhancer.setCallback(callbacks);
        enhancer.setClassLoader(classLoader);
        if(constructorArgs != null && constructorArgs.length > 0){
            return enhancer.create(constructorArgTypes,constructorArgs);
        }
        return enhancer.create();
    }
    private Callback getCallBack(AdvisedSupport advised) {
        return new DynamicAdvisedIcnterceptor(advised.getList(),advised.getTargetSource());
    }
}

CglibAopProxy就是我們代理對(duì)象生成的核心方法。使用 cglib 生成代理類。我們可以與之前ioc框架的代碼。比較發(fā)現(xiàn)區(qū)別就在于:

    Callback callbacks = getCallBack(advised);
    enhancer.setCallback(callbacks);

callback與之前不同了,而是寫了一個(gè)getCallback()的方法,我們就來看看 getCallback 里面的 DynamicAdvisedIcnterceptor到底干了啥。

篇幅問題,這里不會(huì)介紹 cglib 的使用,對(duì)于callback的作用,不理解的同學(xué)需要自行學(xué)習(xí)。

public class DynamicAdvisedInterceptor implements MethodInterceptor{

    protected final List interceptorList;
    protected final TargetSource targetSource;

    public DynamicAdvisedInterceptor(List interceptorList, TargetSource targetSource) {
        this.interceptorList = interceptorList;
        this.targetSource = targetSource;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        MethodInvocation invocation = new CglibMethodInvocation(obj,targetSource.getTagetObject(),method, args,interceptorList,proxy);
        return invocation.proceed();
    }
}

這里需要注意,DynamicAdvisedInterceptor這個(gè)類實(shí)現(xiàn)的 MethodInterceptor 是 gclib的接口,并非我們之前的 AopMethodInterceptor。

我們近距離觀察 intercept 這個(gè)方法我們看到:

MethodInvocation invocation = new CglibMethodInvocation(obj,targetSource.getTagetObject(),method, args,interceptorList,proxy);

通過這行代碼,我們的整個(gè)邏輯終于連起來了。也就是這個(gè)動(dòng)態(tài)的攔截器,把我們通過 CglibMethodInvocation 織入了增強(qiáng)代碼的方法,委托給了 cglib 來生成代理對(duì)象。

至此我們的 Aop 的核心功能就實(shí)現(xiàn)了。

AopBeanFactoryImpl
public class AopBeanFactoryImpl extends BeanFactoryImpl{

    private static final ConcurrentHashMap aopBeanDefinitionMap = new ConcurrentHashMap<>();

    private static final ConcurrentHashMap aopBeanMap = new ConcurrentHashMap<>();

    @Override
    public Object getBean(String name) throws Exception {
        Object aopBean = aopBeanMap.get(name);

        if(aopBean != null){
            return aopBean;
        }
        if(aopBeanDefinitionMap.containsKey(name)){
            AopBeanDefinition aopBeanDefinition = aopBeanDefinitionMap.get(name);
            AdvisedSupport advisedSupport = getAdvisedSupport(aopBeanDefinition);
            aopBean = new CglibAopProxy(advisedSupport).getProxy();
            aopBeanMap.put(name,aopBean);
            return aopBean;
        }

        return super.getBean(name);
    }
    protected void registerBean(String name, AopBeanDefinition aopBeanDefinition){
        aopBeanDefinitionMap.put(name,aopBeanDefinition);
    }

    private AdvisedSupport getAdvisedSupport(AopBeanDefinition aopBeanDefinition) throws Exception {

        AdvisedSupport advisedSupport = new AdvisedSupport();
        List interceptorNames = aopBeanDefinition.getInterceptorNames();
        if(interceptorNames != null && !interceptorNames.isEmpty()){
            for (String interceptorName : interceptorNames) {

                Advice advice = (Advice) getBean(interceptorName);

                Advisor advisor = new Advisor();
                advisor.setAdvice(advice);

                if(advice instanceof BeforeMethodAdvice){
                    AopMethodInterceptor interceptor = BeforeMethodAdviceAdapter.getInstants().getInterceptor(advisor);
                    advisedSupport.addAopMethodInterceptor(interceptor);
                }

                if(advice instanceof AfterRunningAdvice){
                    AopMethodInterceptor interceptor = AfterRunningAdviceAdapter.getInstants().getInterceptor(advisor);
                    advisedSupport.addAopMethodInterceptor(interceptor);
                }

            }
        }

        TargetSource targetSource = new TargetSource();
        Object object = getBean(aopBeanDefinition.getTarget());
        targetSource.setTagetClass(object.getClass());
        targetSource.setTagetObject(object);
        advisedSupport.setTargetSource(targetSource);
        return advisedSupport;

    }

}

AopBeanFactoryImpl是我們產(chǎn)生代理對(duì)象的工廠類,繼承了上一講我們實(shí)現(xiàn)的 IoC 容器的BeanFactoryImpl。重寫了 getBean方法,如果是一個(gè)切面代理類,我們使用Aop框架生成代理類,如果是普通的對(duì)象,我們就用原來的IoC容器進(jìn)行依賴注入。
getAdvisedSupport就是獲取 Aop 框架認(rèn)識(shí)的數(shù)據(jù)結(jié)構(gòu)。

剩下沒有講到的類都比較簡單,大家看源碼就行。與核心邏輯無關(guān)。

寫個(gè)方法測(cè)試一下

我們需要統(tǒng)計(jì)一個(gè)方法的執(zhí)行時(shí)間。面對(duì)這個(gè)需求我們?cè)趺醋觯?/p>

public class StartTimeBeforeMethod implements BeforeMethodAdvice{
    @Override
    public void before(Method method, Object[] args, Object target) {
        long startTime = System.currentTimeMillis();
        System.out.println("開始計(jì)時(shí)");
        ThreadLocalUtils.set(startTime);
    }
}
public class EndTimeAfterMethod implements AfterRunningAdvice {
    @Override
    public Object after(Object returnVal, Method method, Object[] args, Object target) {
        long endTime = System.currentTimeMillis();
        long startTime = ThreadLocalUtils.get();
        ThreadLocalUtils.remove();
        System.out.println("方法耗時(shí):" + (endTime - startTime) + "ms");
        return returnVal;
    }
}

方法開始前,記錄時(shí)間,保存到 ThredLocal里面,方法結(jié)束記錄時(shí)間,打印時(shí)間差。完成統(tǒng)計(jì)。

目標(biāo)類:

public class TestService {
    public void testMethod() throws InterruptedException {
        System.out.println("this is a test method");
        Thread.sleep(1000);
    }
}

配置文件:

[
  {
    "name":"beforeMethod",
    "className":"com.xilidou.framework.aop.test.StartTimeBeforeMethod"
  },
  {
    "name":"afterMethod",
    "className":"com.xilidou.framework.aop.test.EndTimeAfterMethod"
  },
  {
    "name":"testService",
    "className":"com.xilidou.framework.aop.test.TestService"
  },
  {
    "name":"testServiceProxy",
    "className":"com.xilidou.framework.aop.core.ProxyFactoryBean",
    "target":"testService",
    "interceptorNames":[
      "beforeMethod",
      "afterMethod"
    ]
  }
]

測(cè)試類:

public class MainTest {
    public static void main(String[] args) throws Exception {
        AopApplictionContext aopApplictionContext = new AopApplictionContext("application.json");
        aopApplictionContext.init();
        TestService testService = (TestService) aopApplictionContext.getBean("testServiceProxy");
        testService.testMethod();
    }
}

最終我們的執(zhí)行結(jié)果:

開始計(jì)時(shí)
this is a test method
方法耗時(shí):1015ms

Process finished with exit code 0

至此 Aop 框架完成。

后記

Spring 的兩大核心特性 IoC 與 Aop 兩大特性就講解完了,希望大家通過我寫的兩篇文章能夠深入理解兩個(gè)特性。

Spring的源碼實(shí)在是復(fù)雜,閱讀起來常常給人極大的挫敗感,但是只要能夠堅(jiān)持,并采用一些行之有效的方法。還是能夠理解Spring的代碼。并且從中汲取營養(yǎng)。

下一篇文章,我會(huì)給大家講講閱讀開源代碼的一些方法和我自己的體會(huì),敬請(qǐng)期待。

最后

github:https://github.com/diaozxin00...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/68353.html

相關(guān)文章

  • 徒手框架--高并發(fā)環(huán)境下的請(qǐng)求合并

    摘要:我們就可以將這些請(qǐng)求合并,達(dá)到一定數(shù)量我們統(tǒng)一提交??偨Y(jié)一個(gè)比較生動(dòng)的例子給大家講解了一些多線程的具體運(yùn)用。學(xué)習(xí)多線程應(yīng)該多思考多動(dòng)手,才會(huì)有比較好的效果。地址徒手?jǐn)]框架系列文章地址徒手?jǐn)]框架實(shí)現(xiàn)徒手?jǐn)]框架實(shí)現(xiàn) 原文地址:https://www.xilidou.com/2018/01/22/merge-request/ 在高并發(fā)系統(tǒng)中,我們經(jīng)常遇到這樣的需求:系統(tǒng)產(chǎn)生大量的請(qǐng)求,但是這...

    劉東 評(píng)論0 收藏0
  • 徒手框架--實(shí)現(xiàn)IoC

    摘要:從而能夠進(jìn)一步深入了解框架。至此我們框架開發(fā)完成。雖然說閱讀源碼是了解框架的最終手段。但是框架作為一個(gè)生產(chǎn)框架,為了保證通用和穩(wěn)定,源碼必定是高度抽象,且處理大量細(xì)節(jié)。下一篇文章應(yīng)該會(huì)是徒手?jǐn)]框架實(shí)現(xiàn)。 原文地址:https://www.xilidou.com/2018/... Spring 作為 J2ee 開發(fā)事實(shí)上的標(biāo)準(zhǔn),是每個(gè)Java開發(fā)人員都需要了解的框架。但是Spring 的...

    rottengeek 評(píng)論0 收藏0
  • JAVA 中的 CAS

    摘要:我們繼續(xù)看代碼的意思是這個(gè)是一段內(nèi)嵌匯編代碼。也就是在語言中使用匯編代碼。就是匯編版的比較并交換。就是保證在多線程情況下,不阻塞線程的填充和消費(fèi)。微觀上看匯編的是實(shí)現(xiàn)操作系統(tǒng)級(jí)別的原子操作的基石。 原文地址:https://www.xilidou.com/2018/02/01/java-cas/ CAS 是現(xiàn)代操作系統(tǒng),解決并發(fā)問題的一個(gè)重要手段,最近在看 eureka 的源碼的時(shí)候。...

    CocoaChina 評(píng)論0 收藏0
  • 徒手一個(gè)簡單的RPC框架

    摘要:徒手?jǐn)]一個(gè)簡單的框架之前在牛逼哄哄的框架,底層到底什么原理得知了遠(yuǎn)程過程調(diào)用簡單來說就是調(diào)用遠(yuǎn)程的服務(wù)就像調(diào)用本地方法一樣,其中用到的知識(shí)有序列化和反序列化動(dòng)態(tài)代理網(wǎng)絡(luò)傳輸動(dòng)態(tài)加載反射這些知識(shí)點(diǎn)。 徒手?jǐn)]一個(gè)簡單的RPC框架 之前在牛逼哄哄的 RPC 框架,底層到底什么原理得知了RPC(遠(yuǎn)程過程調(diào)用)簡單來說就是調(diào)用遠(yuǎn)程的服務(wù)就像調(diào)用本地方法一樣,其中用到的知識(shí)有序列化和反序列化、動(dòng)態(tài)...

    Gemini 評(píng)論0 收藏0
  • 徒手一個(gè) Spring Boot 中的 Starter ,解密自動(dòng)化配置黑魔法!

    摘要:先來看代碼吧,一會(huì)松哥再慢慢解釋關(guān)于這一段自動(dòng)配置,解釋如下首先注解表明這是一個(gè)配置類。本文的案例,松哥已經(jīng)上傳到上了,地址。我們使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 為我們帶來了眾多的自動(dòng)化配置,有了這些自動(dòng)化配置,我們可以不費(fèi)吹灰之力就能搭建一個(gè)生產(chǎn)級(jí)開發(fā)環(huán)境,有的小伙伴會(huì)覺得這個(gè) Starter 好神奇呀!其實(shí) Starter 也都...

    xiaochao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

weij

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<