23种设计模式之代理模式(一)

代理模式

代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

简而言之,代理模式就是设置一个中间代理(通俗意义上的中介)来控制访问原目标对象,以达到增强原对象的功能和简化访问方式。

静态代理

这种代理方式需要代理对象和目标对象实现一样的接口。
1)创建一个接口

//针对用户访问的接口
public interface UserDao {
   //增加功能
    void add();
    //修改功能
    void update();
    //查询功能
    void select();
    //删除功能
    void delete();
}

2)创建一个目标类

**
 * 针对用户访问数据接口的实现
 */

public class UserDaoImp implements  UserDao {
    @Override
    public void add() {
        System.out.println("增");
    }

    @Override
    public void update() {
        System.out.println("改");
    }

    @Override
    public void select() {
        System.out.println("查");
    }

    @Override
    public void delete() {
        System.out.println("删");
    }
}

3)创建一个代理类

public class JdkProxy {
    public static void main(String[] args) {
        //接口多态测试userDao
        UserDao ud = new UserDaoImp();
        ud.add();
        ud.delete();
        ud.select();
        ud.update();
        System.out.println("----------------------");

        UserDao ud1 = new UserDaoImp2();

        ud1.update();
        ud1.select();
        ud1.delete();
        ud1.add();
        	}
        }

jdk动态代理

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

静态代理与动态代理的区别主要在:
静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件。
动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中。

特点:
动态代理的代理类不需要实现接口,但是要求目标类必须实现接口,否则不能使用动态代理。

动态代理例子
1)接口
在动态代理中,这个接口代理类不需要实现,但是被代理类必须实现,否则不能使用动态代理。
Tips: 静态代理的话,代理类和被代理类都需要实现相同的接口。

public interface IUserDao {
    void addUser();
}

2)目标类

public class UserDao implements IUserDao {
    @Override
    public void addUser() {
        System.out.println("这是目标类 --> 新增用户");
    }
}

3)代理类
动态代理的代理类不需要实现接口,它是动态地在内存中构建代理对象。

public class ProxyFactory {

    // 用这个变量来存储被代理对象。
    private Object target;

    // 代理类的构造方法,把被代理对象作为参数传进去。
    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 为被代理对象生成代理对象
    public Object getProxyInstance() {
        // target.getClass().getClassLoader():被代理类的类加载器
        // target.getClass().getInterfaces():被代理类实现的接口
        // InvocationHandler(): 需要在其中的 invoke() 方法中增强接口中的方法
        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("前置工作");
                        method.invoke(target, args);
                        System.out.println("收尾工作");
                        return null;
                    }
                });
    }
}

4)测试

public class ProxyTest {
    public static void main(String[] args) {
        // 创建一个被代理对象
        IUserDao target = new UserDao();
        // 生成一个代理对象
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
        // 用代理对象执行方法
        proxy.addUser();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值