动态代理

动态代理

一、反射技术

 1 import java.lang.reflect.InvocationTargetException;
 2 import java.lang.reflect.Method;
 3 
 4 public class ReflectService {
 5 
 6     /**
 7      * 服务方法
 8      */
 9     public void sayHello(String name){
10         System.out.println("hello "+name);
11     }
12     
13     /**
14      * 测试
15      * @throws ClassNotFoundException 
16      * @throws IllegalAccessException 
17      * @throws InstantiationException 
18      * @throws SecurityException 
19      * @throws NoSuchMethodException 
20      * @throws InvocationTargetException 
21      * @throws IllegalArgumentException 
22      */
23     
24     public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
25         //通过反射创建ReflectService对象
26         Object service=Class.forName(ReflectService.class.getName()).newInstance();
27         //获取服务方法
28         Method method=service.getClass().getMethod("sayHello", String.class);
29         //反射调用方法
30         method.invoke(service, "zz");
31     }
32     
33 }

  代码通过反射技术去创建ReflectService对象,获取方法后通过反射调用。

二、JDK动态代理

JDK动态代理,是由JDK的java.lang.reflect.*包提供支持的:

1.编写服务类和接口,这是真正的服务提供者,在JDK代理中接口是必须的

2.编写代理类,提供绑定和代理方法

  写一个接口及其实现类

  HelloService.java

public interface HelloService {
    public void sayHello(String name);
}

  HelloServiceImpl.java

public class HelloServiceImpl implements HelloService{

    @Override
    public void sayHello(String name) {
        // TODO Auto-generated method stub
        System.err.println("hello"+name);
        
    }

}

  写一个代理类,提供真实对象的绑定和代理方法

 1 import java.lang.reflect.InvocationHandler;
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.Proxy;
 4 
 5 public class HelloServiceProxy implements InvocationHandler{
 6 
 7     /**
 8      * 真实服务对象
 9      */
10     private Object target;
11     /**
12      * 绑定委托对象并返回一个代理类
13      * 
14      */
15     public Object bind(Object target){
16         this.target=target;
17         //取得代理对象
18         return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
19         //jdk代理需要提供接口
20         /*
21          * param1:类加载器
22          * param2:接口
23          * param3:this代表当前helloServiceProxy类
24          */
25     }
26     @Override
27     /**
28      * 通过代理对象调用方法首先进入这个方法
29      * param1:代理对象
30      * param2:当前调用的方法
31      * param3:方法参数
32      */
33     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
34         // TODO Auto-generated method stub
35         System.err.println("######我是JDK动态代理#####");
36         Object result=null;
37         //反射方法前调用
38         System.err.println("我准备说Hello");
39         //执行方法,相当于调用HelloServiceImpl类的sayHello方法
40         result=method.invoke(target, args);
41         //反射方法后调用
42         System.err.println("我说过Hello了");
43         return result;
44     }
45     
46 }

  测试类

public class HelloServiceMain {

    public static void main(String[] args) {
        HelloServiceProxy helloHandler=new HelloServiceProxy();
        HelloService proxy=(HelloService)helloHandler.bind(new HelloServiceImpl());
        proxy.sayHello("张三");
    }
}

  执行绑定后,在进入代理对象方法调用的时候就会到HelloServiceProxy的代理方法上(invoke方法)

原文地址:https://www.cnblogs.com/zuzZ/p/8107910.html