Java编程思想之代理

一:静态代理

这种代理方式需要代理对象和目标对象实现一样的接口

优点:可以在不修改目标对象的情况下扩展目标对象的功能(经纪人是明星的代理,可以为明星做另外的一些事情)

缺点:

  1. 冗余。由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。
  2. 不易维护。一旦接口增加方法,目标对象与代理对象都要进行修改。

 

举例:

//接口IUserDao

package com.proxy;

 

public interface IUserDao {

    public void save();

}

 

//目标对象UserDao

package com.proxy;

 

public class UserDao implements IUserDao{

 

    @Override

    public void save() {

        System.out.println("保存数据");

    }

}

 

//静态代理对象:UserDapProxy 需要实现IUserDao接口!

package com.proxy;

 

public class UserDaoProxy implements IUserDao{

 

    private IUserDao target;

    public UserDaoProxy(IUserDao target) {

        this.target = target;

    }

   

    @Override

    public void save() {

        System.out.println("开启事务");//扩展了额外功能

        target.save();

        System.out.println("提交事务");

    }

}

 

//测试类:TestProxy

package com.proxy;

 

import org.junit.Test;

 

public class StaticUserProxy {

    @Test

    public void testStaticProxy(){

        //目标对象

        IUserDao target = new UserDao();

        //代理对象

        UserDaoProxy proxy = new UserDaoProxy(target);

        proxy.save();

    }

}

 

输出结果:

开启事务

保存数据

提交事务

 

二:动态代理

1:动态代理利用了JDK API,动态地在内存中构建代理对象,从而实现对目标对象的代理功能。动态代理又被称为JDK代理或接口代理。

2:动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。

3:动态代理利用了反射的机制,我们在运行时动态的利用反射获取目标对象的方法,这个代理代码较为通用,不是为某个具体的目标对象而创建,是一种抽象。

目标接口和目标对象实现相同

//动态代理对象

package com.proxy;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

 

public class ProxyFactory {

 

    private Object target;// 维护一个目标对象

public ProxyFactory(Object target) {

        this.target = target;

    }

 

    // 为目标对象生成代理对象

    public Object getProxyInstance() {

        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),

                new InvocationHandler() {

                 @Override

                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        System.out.println("开启事务");

 

                        // 执行目标对象方法

                        Object returnValue = method.invoke(target, args);

                         System.out.println("提交事务");

                        return null;

                    }

                });

    }

}

 

测试类:

package com.proxy;

 

import org.junit.Test;

 

public class TestProxy {

 

    @Test

    public void testDynamicProxy (){

        IUserDao target = new UserDao();

        System.out.println(target.getClass());  //输出目标对象信息

        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();

        System.out.println(proxy.getClass());  //输出代理对象信息

        proxy.save();  //执行代理方法

    }

}

输出结果:

开启事务

保存数据

提交事务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值