1. 程式人生 > 實用技巧 >JDK、CGLIB、Spring 三種實現代理的區別(三)Spring的ProxyFactory

JDK、CGLIB、Spring 三種實現代理的區別(三)Spring的ProxyFactory

轉:https://blog.csdn.net/sunnycoco05/article/details/78901449

之前兩篇文章中我們說到了JDK proxy和CGLIB實現動態代理的方式,這回說說Spring的方式。Spring中代理物件可通過xml配置方式獲得,也可通過ProxyFactory手動程式設計方式建立物件。我們主要講手動程式設計的方式。Spring中的代理物件其實是JDK Proxy和CGLIB Proxy 的結合。


下面我們使用ProxyFactory的方式建立代理物件,順便看看和JDK的proxy以及CGLIB中的proxy聯絡。
還是使用前兩節中的例子。建立需要代理的類(MyTarget)、介面(PeopleService)及其實現(EnglishService),分別看看對介面和類的代理:

public class MyTarget {
    public void printName() {
        System.err.println("name:Target-");
    }
}

public interface PeopleService {
    public void sayHello();

    public void printName(String name);
}

public class EnglishService implements PeopleService {
    @Override
    public void
sayHello() { System.err.println("Hi~"); } @Override public void printName(String name) { System.err.println("Your name:" + name); } }

下面建立一個MethodInterceptor實現方法呼叫的前後攔截,這裡的攔截只是進行簡單的列印資訊。
這裡需要用到額外的包 aopalliance.jar和aspectjweaver。

mport org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation; public class AroundInteceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.err.println(invocation.getMethod().getName() + "呼叫之前"); Object res = invocation.proceed(); System.err.println(invocation.getMethod().getName() + "呼叫之後"); return res; } }

使用Spring aop包中的ProxyFactory建立代理,並通過addAdvice
增加一個環繞方式的攔截:

package com.spring;

import org.springframework.aop.framework.ProxyFactory;
import org.testng.annotations.Test;

import com.cglib.MyTarget;
import com.proxy.api.PeopleService;
import com.proxy.impl.EnglishService;
import com.spring.aop.AroundInteceptor;

public class ProxyFactoryTest {
    @Test
    public void classProxy() {
        //代理物件未指定介面,使用CGLIB生成代理類
        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(new MyTarget());
        factory.addAdvice(new AroundInteceptor());
        MyTarget targetProxy = (MyTarget) factory.getProxy();
        targetProxy.printName();
        System.err.println(targetProxy.getClass().getName());
    }

    @Test
    public void interfaceProxy() {
        //代理物件指定介面PeopleService,目標類為實現PeopleService的EnglishService,使用JDK proxy生成代理類
        ProxyFactory factory = new ProxyFactory();
        factory.setInterfaces(new Class[] { PeopleService.class });
        factory.addAdvice(new AroundInteceptor());
        factory.setTarget(new EnglishService());
        PeopleService peopleProxy = (PeopleService) factory.getProxy();
        peopleProxy.sayHello();
        System.err.println(peopleProxy.getClass().getName());
    }
}

執行結果分別為: