JDK-代理对象(动态代理的通用模板)

目录

一、静态代理

1、首先编写一个拥有增删改查方法的接口 CrudService

2、再写一个实现类去实现它 CrudServiceImpl

3、再写一个静态代理类来代理 CrudServiceImpl

4、编写一个main方法来调用

5、运行结果

二、动态代理

1、首先编写一个拥有增删改查方法的接口 CrudService

2、再写一个实现类去实现它 CrudServiceImpl

3、再写一个动态代理类来代理 CrudServiceImpl

 4、编写一个main方法来调用

5、运行结果


一、静态代理

        代理类的作用是代理原本的类去做一些附加的事情。比如说,想要在每个代理的方法前都加上一个打印日志方法:如果去修改原代码的话不仅工作量巨大, 还容易破坏原代码的结构,很可能会导致出bug。而且工作中随意修改别人的代码是大忌。所以可以引出代理类的概念。

接下来演示一下实现静态代理的过程

1、首先编写一个拥有增删改查方法的接口 CrudService

public interface CrudService {

    public void add();
    public void delete();
    public void update();
    public void query();

}

2、再写一个实现类去实现它 CrudServiceImpl

public class CrudServiceImpl implements CrudService {

    public void add() {
        System.out.println("添加了一条数据");
    }
    
    public void delete() {}

    public void update() {}

    public void query() {}
}

3、再写一个静态代理类来代理 CrudServiceImpl

// 同样需要实现接口
public class JtDlProxy implements CrudService {  
    // 给代理类一个属性,为普通类
    private CrudServiceImpl crudImpl; 
    // 代理类的构造方法
    public void setCrudImpl(CrudServiceImpl crudImpl) { 
        this.crudImpl = crudImpl;
    }
    // 依旧需要实现接口的所有方法
    public void add() {
        // 执行切面处理(日志打印)
        BeforeLog();
        crudImpl.add();
    }

    public void delete() {}
    public void update() {}
    public void query() {}

    // 用于切面加入的打印日志的方法
    public void BeforeLog(){
        System.out.println("执行方法前的日志");
    }
}

4、编写一个main方法来调用

public static void main(String[] args) {
        // 真实对象
        CrudServiceImpl crudImpl = new CrudServiceImpl();
        // 代理对象
        JtDlProxy jtDlProxy = new JtDlProxy();
        jtDlProxy.setCrudImpl(crudImpl);
        // 通过代理对象来调用
        jtDlProxy.add();
    }

5、运行结果

 在不改动原代码的情况下添加了日志方法,但是依旧显得很繁琐。

二、动态代理

        代理类在程序运行时创建的代理方式被成为动态代理。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。 而且如果需要代理的类太多的话,对每一个类都需要写一个单独的代理类很麻烦,而用了动态代理只需要写一个动态生成代理类程序代码即可。

1、首先编写一个拥有增删改查方法的接口 CrudService

public interface CrudService {

    public void add();
    public void delete();
    public void update();
    public void query();

}

2、再写一个实现类去实现它 CrudServiceImpl

public class CrudServiceImpl implements CrudService {

    public void add() {
        System.out.println("添加了一条数据");
    }
    
    public void delete() {}

    public void update() {}

    public void query() {}
}

3、再写一个动态代理类来代理 CrudServiceImpl

   其中的代码也可以作为通用模板去使用!

// 使用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {

    // 被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    // 生成代理对象
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    // 处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        BeforeLog(method.getName()); // 通过反射调用方法名,来执行切面处理(日志打印)
        // 反射(动态代理的本质就是反射)
        Object result = method.invoke(target, args);
        afterLog(); // 执行切面处理(日志打印)
        return result;
    }
    // 用于切面加入的打印日志的方法
    public void BeforeLog(String str){
        System.out.println("执行"+str+"方法前的日志");
    }
    public void afterLog(){
        System.out.println("执行后的日志");
    }

}

 4、编写一个main方法来调用

public static void main(String[] args) {
        // 真实对象
        CrudServiceImpl crudImpl = new CrudServiceImpl();
        // 调用处理程序类的方法来生成代理对象,并调用接口方法
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        // 构造方法
        pih.setTarget(crudImpl);
        // 动态生成代理类
        CrudService proxy = (CrudService) pih.getProxy();
        // 利用代理类调用接口
        proxy.add();
    }

5、运行结果

 这样就完成了一个动态代理的过程!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值