---------------------- <a href="http://www.itheima.com" target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com" target="blank">.Net培训</a>、期待与您交流! ----------------------
定义一个接口A,A中有一个方法m1,定义一个类B,B实现A接口。要求通过jdk自带api创建B对象的代理类,并调用m1方法。
学习之前还是要先明确几点问题:什么是动态代理?怎样用动态代理?为什么要用动态代理?
一、什么是动态代理?
动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。是在程序运行时,运用反射机制动态创建而成。JDK动态代理中包含一个类和一个接口:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
参数说明: Object proxy:指被代理的对象。
Method method:要调用的方法 Object[]
args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
参数说明:
ClassLoader loader:类加载器
Class<?>[] interfaces:得到全部的接口
二、怎样使用动态代理
我们且看阳哥给的题目:
首先定义一个接口A:
- package interFace;
- public interface A {
- void m1(String s);
- }
- package set;
- import interFace.A;
- public class B implements A{
- @Override
- public void m1(String s) {
- // TODO Auto-generated method stub
- System.out.println(s);
- }
- }
下面我们定义的是动态代理类,该类实现了Java反射包中的InvocationHandler接口。代理实例调用方法时,将对方法调用指派到它的代理处理器程序的invoke方法中。invoke方法内部实现预处理,对委托类方法调用,事后处理等逻辑:
- package set;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- public class DynaHandler implements InvocationHandler {
- //要代理的原始对象
- private Object obj;
- public DynaHandler(Object obj) {
- super();
- // TODO Auto-generated constructor stub
- this.obj = obj;
- }
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // TODO Auto-generated method stub
- Object result = null;
- //调用之前
- doBefore();
- result = method.invoke(obj, args);
- //调用之后
- doAfter();
- return null;
- }
- private void doAfter() {
- // TODO Auto-generated method stub
- System.out.println("调用invoke方法之后。。");
- }
- private void doBefore() {
- // TODO Auto-generated method stub
- System.out.println("调用invoke方法之前。。");
- }
- }
最后我们进行测试:
- package test;
- import interFace.A;
- import java.lang.reflect.Proxy;
- import set.B;
- import set.DynaHandler;
- public class DynamicTest {
- public static void main(String args[]) {
- B b = new B();
- DynaHandler handler = new DynaHandler(b);//代理实例的调用处理程序
- //创建一个实现业务接口的代理类,用于访问业务类。
- //返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序,如ProxyHandler。
- A a = (A) Proxy.newProxyInstance(b.getClass().getClassLoader(), b
- .getClass().getInterfaces(), handler);
- a.m1("Hello HeiMa!");
- }
- }
三、使用动态代理有什么好处?
动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
使用Java动态代理机制的好处:
1、减少编程的工作量。
2、系统扩展性和维护性增强,方便程序修改。
---------------------- <a href="http://www.itheima.com" target="blank">ASP.Net+Unity开发</a>、 <a href="http://www.itheima.com" target="blank">.Net培训</a>、期待与您交流! ----------------------
详细请查看:<a href="http://www.itheima.com" target="blank">www.itheima.com</a>