java设计模式之动态代理

参考来自狂神说java一个讲解java很细腻的up主

1.为什么使用代理

public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("增加用户");
    }

    public void delete() {
        System.out.println("删除用户");
    }

    public void update() {
        System.out.println("更新用户");

    }

    public void Query() {
        System.out.println("查询用户");
    }
}

这是service层。

  • 假设我要在service层执行这些方法之前,之后要拓展些业务。要怎么办?
  1. 我们在每个方法里面加上这些业务就OK了,
  2. 把每个业务写成方法,在给这些方法调用

这应该是我们最原生的想法。

这样有个很大的弊端,万一修改后 逻辑不能正常运行呢,造成业务崩塌

  • 所以我们要在不动原有业务上进行操作怎么办呢?

这个时候我们就可以找代理帮我们做这个事情。

这个图很好的展示了代理的作用。

参考来自狂神说java一个讲解java很细腻的up主

代理的好处:

  • 可以使真实角色操作更加纯粹,不用关注公公业务

  • 公告业务给代理,实现业务分工

  • 公告业务发生拓展,方便集中管理

2.动态代理

1.动态代理需要的环境

  • Proxy类
  • InvocationHandler接口

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
        );
    }

   //处理代理实例返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        log(method.getName());
        Object object = method.invoke(target, args);
        after();
        return object;
    }

    public void log(String msg){
        System.out.println("执行了"+msg+"方法");
    }

    public void  before(){
        System.out.println("======before======");
    }
    public  void after(){
        System.out.println("======after======");

    }
}

这我的理解是是相当于一个代理生成器。(代理工厂的意思)

就是你要代理什么你告诉他,他帮你生成对应的代理。

2.调用代理测试

    @org.junit.Test
    public void  ProxyTest(){
//        1. 真实对象(需要被代理的对象)
        Landlord landlord=new Landlord();
//        2.代理公司---我的理解
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
//        3.把代理对象给代理公司
        proxyInvocationHandler.setTarget(landlord);
//        4.然后得到这个代理
        Rent landlordProxy = (Rent) proxyInvocationHandler.getProxy();
//        5.执行方法
        landlordProxy.Renting();    
    }
执行结果:
======before======
[debug]执行了Renting方法
出租房子!!
======after======

这样在不改变原有的业务上添加了日志

这个动态代理是了解SpringAOP的必经之路,

posted @ 2020-06-10 23:31  shy温温温  阅读(123)  评论(0编辑  收藏  举报