关于JAVA代理机制的理解和实现

关于JAVA代理机制的理解和实现

代理机制

java常用的设计模式就有代理模式,代理机制是通过代理类和委托类实现相同的接口来完成代理过程,在这其中代理类主要是负责预处理、转发消息给委托类,以及处理消息等功能。代理类和委托类之间实现间接关联的关系,代理类不是真正的实现委托类的功能,只是作为一个桥梁的作用,通过代理类来间接实现委托类的功能,并且在这期间代理类可以添加更多的功能。

静态代理

静态代理是直接将代理的具体类、实现方法表现在代码里,在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。具体实现需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.
实现共同的接口:

//基本接口
public interface IPersonDao {
	void update();
}

目标对象:

ublic class PersonDao implements IPersonDao{
		 
			public void update() {
				// TODO Auto-generated method stub
				System.out.println("update方法");
			}
		}

代理类:

public class PersonDaoProxy implements IPersonDao{
			private IPersonDao target;
			
			public PersonDaoProxy(IPersonDao target){
				this.target = target;
			}
			@Override
			public void update() {
				System.out.println("update前记录日志");
				this.target.update();
				System.out.println("update后记录日志");
			}
		}

测试类:

public class App {
			public static void main(String[] args){
				PersonDao p = new PersonDao();
				PersonDaoProxy pProxy = new PersonDaoProxy(p);
				pProxy.update();
			}
		}

输出:

update前记录日志
update方法
update后记录日志

动态代理

在代码运行期间加载被代理的类这就是动态代理,Spring AOP机制就是动态代理机制。

1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理

同样共同接口:

public interface Person {
    //上交班费
    void giveMoney();
}

委托类:

public class Student implements Person {
    private String name;
    public Student(String name) {
        this.name = name;
    }
    
    @Override
    public void giveMoney() {
        try {
          //间隔时间
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       System.out.println(name + "交50元");
    }
}

工具类:

public class MonitorUtil {
    
    private static ThreadLocal<Long> tl = new ThreadLocal<>();
    
    public static void start() {
        tl.set(System.currentTimeMillis());
    }
    
    //结束时打印耗时
    public static void finish(String methodName) {
        long finishTime = System.currentTimeMillis();
        System.out.println(methodName + "方法耗时" + (finishTime - tl.get()) + "ms");
    }
}

代理类:

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


public class StuInvocationHandler<T> implements InvocationHandler {
	   //invocationHandler持有的被代理对象
	    T target;
	    
	    public StuInvocationHandler(T target) {
	       this.target = target;
	    }
	    
	    /**
	     * proxy:代表动态代理对象
	     * method:代表正在执行的方法
	     * args:代表调用目标方法时传入的实参
	     */
	    @Override
	    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	        System.out.println("代理执行" +method.getName() + "方法");
	        //代理过程中插入监测方法,计算该方法耗时
	        MonitorUtil.start();
	        Object result = method.invoke(target, args);
	        MonitorUtil.finish(method.getName());
	        return result;
	    }

	}

测试类:

public class ProxyTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建一个实例对象,这个对象是被代理的对象
        Person zhangsan = new Student("张三");
        
        //创建一个与代理对象相关联的InvocationHandler
        InvocationHandler stuHandler = new StuInvocationHandler<Person>(zhangsan);
        
        //创建一个代理对象stuProxy来代理zhangsan,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
        Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);

       //代理执行交班费的方法
        stuProxy.giveMoney();
	}

}

输出:

代理执行giveMoney方法
张三上交班费50元
giveMoney方法耗时1009ms

以上文章参考于://https://www.cnblogs.com/gonjan-blog/p/6685611.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值