欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)動(dòng)態(tài)代理的實(shí)例代碼

 更新時(shí)間:2021年09月28日 12:47:37   作者:隨身電源  
代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等,這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)動(dòng)態(tài)代理的相關(guān)資料,需要的朋友可以參考下

前言

動(dòng)態(tài)代理在Java中有著廣泛的應(yīng)用,比如Spring AOP、Hibernate數(shù)據(jù)查詢、測(cè)試框架的后端mock、RPC遠(yuǎn)程調(diào)用、Java注解對(duì)象獲取、日志、用戶鑒權(quán)、全局性異常處理、性能監(jiān)控,甚至事務(wù)處理等。

代理,指的是使用代理對(duì)象代替對(duì)其它對(duì)象的訪問,簡(jiǎn)單點(diǎn)說,你求職時(shí)找的中介就是代理,那么在Java中,代理如何體現(xiàn)呢?

靜態(tài)代理

我們首先需要知道,何為靜態(tài)代理?靜態(tài)代理指的是在編譯期就對(duì)目標(biāo)對(duì)象的方法進(jìn)行增強(qiáng),例如:

public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService{

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("發(fā)送了一封郵件,內(nèi)容為:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailService = new EmailServiceImpl();
        emailService.sendEmail("hello");
    }
}

現(xiàn)在若是想在發(fā)送郵件之前獲取一下當(dāng)前的時(shí)間,則可以使用代理類對(duì)發(fā)郵件的方法進(jìn)行增強(qiáng):

public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService{

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("發(fā)送了一封郵件,內(nèi)容為:" + emailContent);
        }
    }

    static class EmailProxy implements EmailService{

        private final EmailService emailService;

        public EmailProxy(EmailService emailService) {
            this.emailService = emailService;
        }

        @Override
        public void sendEmail(String emailContent) {
            System.out.println(LocalDateTime.now());
            emailService.sendEmail(emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailProxy = new EmailProxy(new EmailServiceImpl());
        emailProxy.sendEmail("hello");
    }
}

靜態(tài)代理的缺點(diǎn)非常明顯,編寫麻煩,且可擴(kuò)展性不強(qiáng),而動(dòng)態(tài)代理的出現(xiàn),將徹底解決這些問題。

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

動(dòng)態(tài)代理與靜態(tài)代理恰恰相反,動(dòng)態(tài)代理是在運(yùn)行期對(duì)目標(biāo)對(duì)象的某個(gè)方法進(jìn)行增強(qiáng),比如仍然是發(fā)郵件的服務(wù),使用動(dòng)態(tài)代理,即可這樣實(shí)現(xiàn):

public class TestDemo {

    interface EmailService {
        void sendEmail(String emailContent);
    }

    static class EmailServiceImpl implements EmailService {

        @Override
        public void sendEmail(String emailContent) {
            System.out.println("發(fā)送了一封郵件,內(nèi)容為:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailService emailService = new EmailServiceImpl();
        EmailService emailProxy = (EmailService) Proxy.newProxyInstance(EmailServiceImpl.class.getClassLoader(), EmailServiceImpl.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(LocalDateTime.now());
                Object result = method.invoke(emailService, args);
                return result;
            }
        });
        emailProxy.sendEmail("hello");
    }
}

使用JDK提供的Proxy和InvocationHandler類能夠輕松實(shí)現(xiàn)動(dòng)態(tài)代理,但這種方式也是有局限性的,就是被增強(qiáng)的類必須實(shí)現(xiàn)了接口,因?yàn)镻roxy的參數(shù)中需要接收類的接口信息。

CGLib實(shí)現(xiàn)動(dòng)態(tài)代理

CGLib的出現(xiàn),打破了這一僵局,使用CGLib,能夠增強(qiáng)任意的對(duì)象方法,即使你沒有實(shí)現(xiàn)任何接口,因?yàn)樗峭ㄟ^繼承的方式進(jìn)行增強(qiáng)的。

下面就來演示一下如何使用CGLib,首先引入依賴:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

實(shí)現(xiàn)如下:

public class TestDemo {

    static class EmailServiceImpl {
        public void sendEmail(String emailContent) {
            System.out.println("發(fā)送了一封郵件,內(nèi)容為:" + emailContent);
        }
    }

    public static void main(String[] args) {
        EmailServiceImpl emailService = new EmailServiceImpl();
        EmailServiceImpl emailProxy = (EmailServiceImpl) Enhancer.create(emailService.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println(LocalDateTime.now());
                Object obj = methodProxy.invokeSuper(o, args);
                return obj;
            }
        });
        emailProxy.sendEmail("hello");
    }
}

它的寫法與JDK提供的方式類似,通過Enhancer類的create()方法即可增強(qiáng)一個(gè)對(duì)象,并傳入對(duì)象的Class對(duì)象和一個(gè)MethodInterceptor接口的實(shí)現(xiàn)類,并在intercept()方法中對(duì)原方法進(jìn)行增強(qiáng)。

總結(jié)

到此這篇關(guān)于Java實(shí)現(xiàn)動(dòng)態(tài)代理的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)動(dòng)態(tài)代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論