动态代理对象Proxy的三个参数

前言:

张三作为被告被告杀人,张三申述自己没有杀人,

可是自己不懂法,便找来律师作为代理为自己辩护。

接口类准备

1.打官司接口
public interface Court {
     //定义一个方法 要求所有参与到打官司中的角色都有 打官司的功能
    int doCourt(int a);
    int speak();
}

2.张三打官司(被代理的人的实现类)
public class Person implements Court{
    private String name;

    //有参  无参构造方法
    public Person() {
    }
    public Person(String name) {
        this.name = name;
    }

    //getter和setter器
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    //重写接口doCourt speak两个方法
    @Override
    public int doCourt( int a) {
        System.out.println(name+"说:我没杀人");
        return a*10;
    }
    @Override
    public int speak() {
        return 5;
    }

    //定义一个eat方法
    public void eat(){

    }
}

3.律师替张三打官司(动态代理对象)
public class TestProxy {
    public static void main(String[] args) {
        // 张三请律师打官司
        Person person=new Person("张三");
		

        // JDK Proxy(代理对象): Proxy.newProxyInstance 方法的三个参数
		//创建代理对象 增强 person对象 使用代理对象代替person 去执行 doCourt方法
        // 参数1 类加载器
        ClassLoader classLoader = person.getClass().getClassLoader();
        // 参数2 被代理对象实现的所有的接口的字节码数组
        Class[] interfaces =person.getClass().getInterfaces();// {Court.class , ... , ...};
		//Class[] interfaces={Court.class};
        // 参数3 执行处理器 用于定义方法的增强规则(加强后的方法)
        InvocationHandler handler =new InvocationHandler(){
            //当代理对象调用了接口中的任何一个方法 都会将该方法以method对象的形式传入 invoke方法
            //1. proxy  代理对象  2.method 被代理对象的方法  3.args 被代理对象 方法被调用时 传入的实参 数组 4.return null; 返回被增强方法的结果
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// 当执行 被代理的方法 是  doCourt 的时候 增强 如果是其他方法 让其正常执行即可
                Object res =null;				
                if(method.getName().equals("doCourt")){
                    System.out.println("律师取证:证据证明,案发当时 当事人在 酒店 谈一个项目");                  
                    res =method.invoke(person,args);// 让被代理对象原有的方法执行            
                    System.out.println("证据显示:当事人不具备作案时间,不可能去杀人");// 律师添加其他的增强代码
                }else{                              // 其他方法 执行原有方法,不加强  例如:speak
                    res =method.invoke(person,args);
                }             
                return res;// 返回运行结果
            }
        };

        Court lawyer = (Court)Proxy.newProxyInstance(classLoader,interfaces,handler);
        // 使用 代理对象 代替person对象去完成打官司的功能
        int x =lawyer.doCourt(10);  //代理对象lawyer调用接口方法
		
        System.out.println(x);      //10
    }
}
总结
1.在不修改原有代码的 或者没有办法修改原有代码的情况下  增强对象功能  
   使用代理对象 代替原来的对象去完成功能  进而达到拓展功能的目的
2.JDK Proxy 动态代理面向接口的动态代理  
   2.1 一定要有接口和实现类的存在 代理对象增强的是实现类 在实现接口的方法重写的方法   
   2.2 生成的代理对象只能转换成 接口的实现类 不能转换成 被代理对象
       例如:Court lawyer = (Court)Proxy.newProxyInstance(classLoader,interfaces,handler);
         不能写成:Person lawyer = (Person)Proxy.newProxyInstance(classLoader,interfaces,handler);
   2.3 代理对象只能增强接口中定义的方法  实现类中其他和接口无关的方法是无法增强的
   2.4 代理对象只能读取到接口中方法上的注解 不能读取到实现类方法上的注解
发布了53 篇原创文章 · 获赞 0 · 访问量 1680

猜你喜欢

转载自blog.csdn.net/weixin_45450428/article/details/102810679