使用JDK动态代理实现拦截器

Dog类
public interface Dog   
{   
    public void info();   
  
    public void run();   
}  

实现Dog类
public class DogImpl implements Dog   
{   
    public void info()   
    {   
        System.out.println("我是一匹狼");   
    }   
    public void run()   
    {   
        System.out.println("我奔跑迅速");   
    }   
}  


拦截Dog实例的拦截器的拦截器类。
public class DogIntercepter   
{   
    public void method1()   
    {   
        System.out.println("=====模拟通用方法一=====");   
    }   
  
    public void method2()   
    {   
        System.out.println("=====模拟通用方法二=====");   
    }   
}  

下面是JDK反射体系里的一个接口,它可以动态调用目标对象的方法。该类实现了java.lang.reflect.InvocationHandler接口。
public class ProxyHandler implements InvocationHandler   
{   
    private Object target;   
    DogIntercepter di = new DogIntercepter();   
    public Object invoke(Object proxy, Method method, Object[] args)throws Exception   
    {   
        Object result = null;   
        if (method.getName().equals("info"))   
        {   
            di.method1();   
            result = method.invoke(target, args);   
            System.out.println("methodname=="+method.getName());   
            System.out.println("target==="+target);   
            System.out.println("proxy==="+proxy);   
            di.method2();   
        }   
        else   
        {   
            result = method.invoke(target, args);   
        }   
        System.out.println("result="+result);   
        return result;   
    }   
    public void setTarget(Object o)   
    {   
        this.target = o;   
    }   
} 

系统还需要提供一个代理工厂,它的主要作用就是根据目标对象生成一个代理对象。
public class MyProxyFactory   
{   
    public static Object getProxy(Object object)   
    {   
       //Dog控制类 代理的操作类   
        ProxyHandler handler = new ProxyHandler();   
       //把该dog实例托付给代理操作   
        handler.setTarget(object);   
        //第一个参数是用来创建 动态代理 的ClassLoader对象,只要该对象能访问Dog接口即可。   
        //也就只要DogImpl与Dog在同一   
        System.out.println("111---"+object.getClass());   
        System.out.println("222---"+object.getClass().getInterfaces()[0]);   
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),handler);   
    }   
} 

Proxy.newProxyInstance方法根据接口数组动态创建代理实例,接口数组通过object.getClass().getInterfaces()方法获得,该类实现传入参数里接口数组的全部接口,因此Dynamic Proxy要求被代理的必须是接口的实现类,否则无法为其构造相应的动态实例。
下面是主程序:
public class TestDog   
{   
    public static void main(String[] args)    
    {   
        Dog targetObject = new DogImpl();   
        Dog dog = null;   
        Object proxy = MyProxyFactory.getProxy(targetObject);   
        System.out.println("proxy="+proxy.getClass().getName());   
        if (proxy instanceof Dog)   
        {   
            dog = (Dog)proxy;   
            System.out.println(dog.getClass());   
        }   
          dog.info();//dog是代理类,当它调用方法时,会自动调用InvocationHandler子类的invoke方法   
          dog.run();   
    }   
}

你可能感兴趣的:(java,jdk)