zoukankan      html  css  js  c++  java
  • Java 反射之JDK动态代理

             Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类。如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类;如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例。

           Proxy提供了如下两个方法来创建动态代理类和动态代理类:

           (1)、static Class<?>  getProxyClass(ClassLoader loader,Class<?> ...interfaces) : 创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口。第一个ClassLoader指定生成动态代理类的类加载器。

           (2)、static Object newProxyInstance(ClassLoader loader,Class<?>  interfaces, InvocationHandler  h) :直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替换成执行          InvocationHandler对象的invoke方法。

           实际上,即使采用第一种方式获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象。也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。

           下面是AOP动态代理的实现:

            在方法前后加入一写通用方法,比如项目中的日志记录。

           Dog.java 

    package com.reflect.proxy;
    
    public interface Dog {
    	public void info();
    	public void run();
    }
    
    GunDog.java

    package com.reflect.proxy;
    
    public class GunDog implements Dog {
    
    	@Override
    	public void info() {
    		System.out.println("我是一只猎狗");
    	}
    	
    	@Override
    	public void run() {
    		System.out.println("我奔跑迅速");
    	}
    
    }
    

    DogUtil.java

    package com.reflect.proxy;
    
    public class DogUtil {
    	
    	
    	public void method1(){
    		System.out.println("=====模拟第1个通用方法======");
    	}
    	
    	public void method2(){
    		System.out.println("=====模拟第2个通用方法======");
    	}
    
    }
    
    借助于Proxy和InvocationHandler就可以实现:当程序调用info()方法和run()方法时,系统就可以“自动” 将method1()和method2() 两个通用方法插入info()和run()犯法

    package com.reflect.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class MyInvocationHandler implements InvocationHandler {
    	
    	//需要被代理的对象
    	private Object target;
    	
    	public void setTarget(Object target){
    		this.target=target;
    	}
    	
    	//指定动态代理的所有方法时,都会替换成执行如下的invoke方法
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		DogUtil du=new DogUtil();
    		
    		//执行DogUtil中的method1
    		du.method1();
    		//以target为主掉来执行method方法
    		Object result=method.invoke(target, args);
    		System.out.println(result);
    		//执行DogUtil中的Method2
    		du.method2();
    		return result;
    	}
    
    }
    

    为指定的target生成代理类.

    package com.reflect.proxy;
    
    import java.lang.reflect.Proxy;
    
    public class MyProxyFactory {
    	
    	//为指定target生成动态代理对象
    	public static Object getProxy(Object target){
    		MyInvocationHandler handler=new MyInvocationHandler();
    		//为MyInvotationHandler设置target对象
    		handler.setTarget(target);
    		//创建并返回一个动态代理
    		return  Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
    	}
    }
    

    测试类

    package com.reflect.proxy;
    
    public class Test {
    
    	public static void main(String[] args) {
    		
    		//创建一个原始的GunDog对象,作为target
    		Dog target=new GunDog();
    		//以指定的target创建动态代理
    		Dog dog=(Dog) MyProxyFactory.getProxy(target);
    		dog.info();
    		dog.run();
    	}
    }
    

    输出:

    =====模拟第1个通用方法======
    我是一只猎狗
    =====模拟第2个通用方法======
    
    
    =====模拟第1个通用方法======
    我奔跑迅速
    =====模拟第2个通用方法======
    
    


  • 相关阅读:
    IK 用java 代码实现分词
    杭电2017
    线性表学习
    一个比较有意思的C语言问题
    杭电1020
    python注释
    Java API —— 递归
    Java API —— File类
    Java API —— 异常
    Map集合案例
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300338.html
Copyright © 2011-2022 走看看