简单了解spring中用到的代理模式


静态代理:

1、代理对象和目标对象都要实现的   公共接口

2、代理对象持有目标对象引用,重写构造方法,

3、实现共同的方法,代理对象增强行为。


缺点:

代理角色固定,一次只能代理一个对象。



接口

public interface Marry {
    void marry();
}

目标对象

public class You implements Marry {
    public void marry() {
        System.out.println("sihai get marry");
    }
}

代理对象

public class MarryCompany implements Marry {
    private You you;
    public MarryCompany(You you) {
        this.you = you;
    }
    public void marry() {
        before();
        you.marry();
        after();
    }

    private void after() {
        System.out.println("get after work done");
    }

    private void before() {
        System.out.println("get ready for marry");
    }
}
测试

public class TestMarry {
    public static void main(String[] args) {
        You you = new You();
        MarryCompany marryCompany = new MarryCompany(you);
        marryCompany.marry();
    }
}

结果

get ready for marry
sihai get marry
get after work done

动态代理

根据需要通过反射机制在程序运行期动态的为目标对象创建代理对象,代理的行为可以代理多个方法,即满足生产需要的同时又达到代码的通用目的。

动态代理有两种实现方法:JDK方式和cglib方式。
区别
jdk动态代理的目标对象必须有接口,且创建的代理对象也是需要转化成接口类型去执行方法,达到增强目标对象行为的目的。这个过程制作快,执行慢。
cglib动态代理以 继承 来实现,主要解决没有接口类的代理实现。 这个过程制作慢,执行快。

JDK动态代理:

接口Marry和目标对象You不变

动态代理类

/**
 * JDK动态代理:
 *  1. 目标对象要有接口,且最后创建的代理对象要转换成此接口类型,来调用方
 *  2. 动态代理类实现InvocationHandler接口,持有目标对象引用,利用构造器动态传入目标对象
 *  3. 使用proxy.newProxyInstance()来动态地创建代理对象
 *  4. 代理对象重写invoke方法,利用反射调用目标对象的方法,同时增加行为
 */
public class JDKHandler implements InvocationHandler {

    //目标对象引用
    private Object target;

    //构造器,可以动态传入目标对象
    public JDKHandler(Object target) {
        this.target = target;
    }

    //创建代理对象
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //利用反射机制调用目标对象的方法,并增强行为
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(target,args);
        after();
        return result;
    }

    private void after() {
        System.out.println("get after work done");
    }

    private void before() {
        System.out.println("get ready for marry");
    }
}
测试
public class MarryTest {
    public static void main(String[] args) {
        //动态代理类,利用构造器传入目标对象        
	JDKHandler jdkHandler = new JDKHandler(new You());
//创建代理对象 Marry marryProxy = (Marry) jdkHandler.getProxy(); //代理对象调用方法,会增加目标对象的行为 marryProxy.marry(); }}



cgib动态代理

目标对象无要求,最后创建的动态代理会转换成此目标对象类型,去调用方法实现行为增强。
/**
 * cglib动态代理
 * 1. 目标对象
 * 2. 实现MethodInterceptor接口,持有目标对象引用,利用构造器动态传入目标对象
 * 3. 重写intercept方法,实现行为增强
 */
public class CglibInterceptor implements MethodInterceptor {
    //目标对象
    private Object target;
    //构造器
    public CglibInterceptor(Object target){
        this.target=target;
    }
    //动态创建代理对象
    public Object getProxy(){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    //行为增强
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        after();
        Object result = methodProxy.invoke(target,objects);
        return result;
    }

    private void after() {
        System.out.println("after");
    }

    private void before() {
        System.out.println("before");
    }
}

目标对象
public class Hello {
    public void print(){
        System.out.println("hello");
    }
}
测试
public class Test {
    public static void main(String[] args) {
        //动态代理类
        CglibInterceptor cglibInterceptor = new CglibInterceptor(new Hello());
        //创建代理,且需要转换成目标对象类型
        Hello proxy = (Hello) cglibInterceptor.getProxy();
        //代理对象调用方法,行为会得到增强
        proxy.print();
    }
}




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值