zoukankan      html  css  js  c++  java
  • java静态代理与动态代理

    代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个真实对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

    1、静态代理

    静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。

    静态代理通常用于对原有业务逻辑的扩充。比如持有二方包的某个类,并调用了其中的某些方法。然后出于某种原因,比如记录日志、打印方法执行时间,但是又不好将这些逻辑写入二方包的方法里。所以可以创建一个代理类实现和二方方法相同的方法,通过让代理类持有真实对象,然后在原代码中调用代理类方法,来达到添加我们需要业务逻辑的目的。

    这其实也就是代理模式的一种实现,通过对真实对象的封装,来实现扩展性。

    一个典型的代理模式通常有三个角色,这里称之为**代理三要素**

    共同接口

    package com.ken.staticproxy;
    
    public interface Person {
    	 void giveMoney();
    	 }
    

      

    真实对象

    package com.ken.staticproxy;
    
    public class Student implements Person {
    
        private String name;
        public Student(String name) {
            this.name = name;
        }
    	@Override
    	public void giveMoney() {
    		// TODO Auto-generated method stub
    		System.out.println(name + "上交班费50元");
    	}
    
    }
    

      

    代理对象

    package com.ken.staticproxy;
    
    public class StudentProxy implements Person {
    
    	Student stu;
        
        public StudentProxy(Person stu) {
            // 只代理学生对象
            if(stu.getClass() == Student.class) {
                this.stu = (Student)stu;
            }
        }
    	@Override
    	public void giveMoney() {
    		// TODO Auto-generated method stub
    		System.out.println("this is proxy start!");
    		stu.giveMoney();
    		System.out.println("this is proxy end!");
    	}
    
    }
    

      测试

    package com.ken.staticproxy;
    
    public class Test {
    
    	public static void main(String[] args) {
    		Person person = new Student("test");
    		person.giveMoney();
    		
    		System.out.println("-------------------------");
    		Person  proxy = new StudentProxy(person);
    		proxy.giveMoney();
    	}
    }
    

      输出结果

    test上交班费50元
    -------------------------
    this is proxy start!
    test上交班费50元
    this is proxy end!

    静态代理的优点和缺点

    先看看代理模式的优点: 扩展原功能,不侵入原代码。

    再看看这种代理模式的缺点:如果需要扩展的扩展的功能模块太多则需要增加更多的方法

    2、动态代理

    代理类在程序运行时创建的代理方式被成为动态代理。 我们上面静态代理的例子中,代理类(studentProxy)是自己定义好的,在程序运行之前就已经编译完成。然而动态代理,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。 比如说,想要在每个代理的方法前都加上一个处理方法:

    动态代理实现

    使用动态代理,需要将要扩展的功能写在一个InvocationHandler 实现类里:

    这个Handler中的invoke方法中实现了代理类要扩展的公共功能。

    public class StudentProxy implements InvocationHandler{
        
    	private Object realObject;
    
        public StudentProxy(Object realObject) {
            this.realObject = realObject;
        }
    
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //代理扩展逻辑
            System.out.println("this is proxy start!");
           Object object =  method.invoke(realObject, args);
           System.out.println("this is proxy end!");
            return object;
        }
    }
    

      

      测试

    Proxy.newProxyInstance 传入的是一个ClassLoader, 一个代理接口,和我们定义的handler,返回的是一个Proxy的实例。

    import java.lang.reflect.Proxy;
    
    public class Test {
    
    	public static void main(String[] args) {
    		Person person = new Student("test");
    		person.giveMoney();
    		
    		System.out.println("-------------------------");
    		Person proxy = (Person) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Person.class}, new StudentProxy(person)); 
    		proxy.giveMoney();
    		
    	}
    }
    

      

      输出结果

    test上交班费50元
    -------------------------
    this is proxy start!
    test上交班费50元
    this is proxy end!
    

      

  • 相关阅读:
    JQuery--常用选择器总结
    ASP.NET MVC- ActionFilter的使用
    C#--DataTable与Dataset的互相转换
    C#--List转DataTable(或DataSet)
    JavaScript--遍历table中的tr存对象
    JavaScript--删除Table中当前行
    JavaScript--判断字符是否为空
    JavaScript--为对象动态添加属性和值
    asp.net mvc 单图片上传
    asp.net mvc 多图片上传
  • 原文地址:https://www.cnblogs.com/xuchaoqi/p/8689177.html
Copyright © 2011-2022 走看看