动态代理
一、反射技术
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方法)