栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

静态代理与动态代理的思考

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

静态代理与动态代理的思考

静态代理:

通过set或者构造的方式将需要代理的类注入到代理类中,所以可以知道的是:

代理类也是在编译阶段生成,然后他就会变成.class文件中,可以理解为编译增强

package com.huang.demo02;

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

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

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

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

代理类:

package com.huang.demo02;

public class Proxy implements UserService {
    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    @Override
    public void add() {
        log("add");
        userService.add();
    }

    @Override
    public void delete() {
        log("delete");
        userService.delete();
    }

    @Override
    public void update() {
        log("update");
        userService.update();
    }

    @Override
    public void query() {
        log("query");
        userService.query();
    }

    private void log(String str) {
        System.out.println("使用了" + str + "方法");
    }
}

缺点:

从上面代码可以看出,代理类代理的方法是通过:注入来的被代理对象调用的,如果接口增加了方法或者修改了方法,那么被代理对象与代理类都需要修改维护;这样就比较不方便;

 动态代理:

代理类在运行时创建,AOP框架不会去修改字节码,所以说硬盘中是没有代理对象的,那么它的对象是在何时产生的?都说了在运行时创建,那么它是不是在内存中产生的代理对象的;这样的话维护成本就比较小;(牛逼之处:通过反射得到目标对象以及目标对象方法,以至于不需要再维护代理类了)

package com.huang.demo04;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//用这个类自动生成代理
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;

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

    //生成得到代理对象
    public Object getProxy() {
        System.out.println("看看是不是得到类加载器,啥样子"+this.getClass().getClassLoader());
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    //处理代理实例并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }
    public void log(String str){
        System.out.println("打印了"+str+"方法");
    }
}

代理三部曲:1.被代理的接口 ,利用set或构造将其注入;2.得到代理对象: 利用Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces, this); //这里的this指的是实现InvocationHandler的类

看到这里,联想一下上面的话,是不是就知道Proxy对象如何产生的了:得到它的加载器将其加载到内存,根据target,也就是对象接口,和InvocationHandler得到对应的代理对象;

用户类:

package com.huang.demo04;

import com.huang.demo02.UserService;
import com.huang.demo02.UserServiceImpl;

public class Client {
    public static void main(String[] args) {
        //真实角色
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色(不存在)
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setTarget(userService);//设置要处理的对象
        //动态生成代理类
        UserService us = (UserService) pih.getProxy();
        us.add();
        us.delete();
    }
}

1.先得到真实角色 2.然后得到代理角色 3.然后将真实角色注入到代理角色当中 4.生成代理类对象 5.利用代理对象,调用方法,完事;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/697276.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号