动态代理(1)----JDK动态代理 .

JavaJava.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成JDK动态代理类或动态代理对象.

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

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

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

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

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

程序中生成动态代理对象可以采用先生成一个动态代理类,然后通过动态代理类来创建对象的方式来生成一个动态代理对象.如下代码片段

  1. //创建一个InvocationHandler对象   
  2.     InvocationHandler handler=new MyInvocationHandler(...);  
  3.     //使用Proxy生成一个动态代理类proxyClass   
  4.     Class proxyClass=Proxy.getProxyClass(Foo.class.getClassLoader(),new Class[]{Foo.class});  
  5.     //获取proxyClass类中带一个InvocationHandler参数的构造器   
  6.     Constructor<T> ctor =proxyClass.getConstructor(new Class[]{InvocationHandler.class});  
  7.     //调用ctor的newInstance方法来创建动态实例   
  8.     Foo f=(Foo)ctor.newInstance(new Object[]{handler});  
//创建一个InvocationHandler对象
	InvocationHandler handler=new MyInvocationHandler(...);
	//使用Proxy生成一个动态代理类proxyClass
	Class proxyClass=Proxy.getProxyClass(Foo.class.getClassLoader(),new Class[]{Foo.class});
	//获取proxyClass类中带一个InvocationHandler参数的构造器
	Constructor<T> ctor =proxyClass.getConstructor(new Class[]{InvocationHandler.class});
	//调用ctor的newInstance方法来创建动态实例
	Foo f=(Foo)ctor.newInstance(new Object[]{handler});

上面代码可以简化成如下代码

  1. //创建一个InvocationHandler对象   
  2.     InvocationHandler hanlder=new MyInvocationHandler(...);  
  3.     //使用Proxy直接生成一个动态代理对象   
  4.     Foo f=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);  
//创建一个InvocationHandler对象
	InvocationHandler hanlder=new MyInvocationHandler(...);
	//使用Proxy直接生成一个动态代理对象
	Foo f=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);

下面程序示范了使用ProxyInvocationHandler来生成动态代理对象

  1. public class ProxyTest {  
  2.     public static void main(String[] args) throws Exception{  
  3.         //创建一个InvocationHandler对象   
  4.         InvocationHandler handler=new MyInvokationHandler();  
  5.         //使用指定的InvocationHanlder来生成一个动态代理对象   
  6.         PersonPro p=(PersonPro)Proxy.newProxyInstance(PersonPro.class.getClassLoader(), new Class[]{PersonPro.class}, handler);  
  7.         //调用动态代理对象的walk()方法和sayHello()方法   
  8.         p.walk();  
  9.         p.sayHello("luck");  
  10.     }  
  11. }  
  12. interface PersonPro{  
  13.     void walk();  
  14.     void sayHello(String name);  
  15. }  
  16. class MyInvokationHandler implements InvocationHandler{  
  17.     /* 
  18.      * 执行动态代理对象的所有方法时,都会被替换成执行如下invoke方法 
  19.      * 其中: 
  20.      * proxy--代表动态代理对象 
  21.      * method--代表正在执行的方法 
  22.      * args--代表执行代理对象方法时传入的实参 
  23.      */  
  24.     public Object invoke(Object proxy,Method method,Object[] args){  
  25.         System.out.println("正在执行的方法:"+method);  
  26.         if(args!=null){  
  27.             System.out.println("下面是执行该方法时传入的实参:");  
  28.             for(Object val:args){  
  29.                 System.out.println(val);  
  30.             }  
  31.         }else{  
  32.             System.out.println("调用该方法无须实参");  
  33.         }  
  34.         return null;  
  35.     }  
  36. }  
public class ProxyTest {
	public static void main(String[] args) throws Exception{
		//创建一个InvocationHandler对象
		InvocationHandler handler=new MyInvokationHandler();
		//使用指定的InvocationHanlder来生成一个动态代理对象
		PersonPro p=(PersonPro)Proxy.newProxyInstance(PersonPro.class.getClassLoader(), new Class[]{PersonPro.class}, handler);
		//调用动态代理对象的walk()方法和sayHello()方法
		p.walk();
		p.sayHello("luck");
	}
}
interface PersonPro{
	void walk();
	void sayHello(String name);
}
class MyInvokationHandler implements InvocationHandler{
	/*
	 * 执行动态代理对象的所有方法时,都会被替换成执行如下invoke方法
	 * 其中:
	 * proxy--代表动态代理对象
	 * method--代表正在执行的方法
	 * args--代表执行代理对象方法时传入的实参
	 */
	public Object invoke(Object proxy,Method method,Object[] args){
		System.out.println("正在执行的方法:"+method);
		if(args!=null){
			System.out.println("下面是执行该方法时传入的实参:");
			for(Object val:args){
				System.out.println(val);
			}
		}else{
			System.out.println("调用该方法无须实参");
		}
		return null;
	}
}

上面程序中提供了一个Person接口,该接口中包含了walksayHello两个抽象方法,接着程序定义了一个简单的InvocationHandler实现类,定义该实现类时需要重写invoke方法----执行代理对象所有方法执行时将会替换成执行此invoke方法.

从运行结果中可以看出,不管程序执行代理对象的walk()方法,还是执行代理对象的sayHello()方法,实际上都是执行InvocationHandler对象的invoke()方法.

下一篇文章将实现SpringAOP的动态代理的demo

基于接口的动态代理是Java语言提供的一个强大的特性,它允许我们在运行时创建新的代理对象,这个代理对象实现了我们指定的一系列接口,并且可以拦截并修改接口方法的执行过程。这一功能主要通过`java.lang.reflect.Proxy`和`InvocationHandler`接口来实现。 以下是基本步骤: 1. **定义接口**:首先,你需要确定要代理的接口,这个接口将作为代理对象的行为规范。 ```java public interface MyInterface { void doSomething(); } ``` 2. **创建InvocationHandler**:这是核心部分,它包含了对实际方法的处理逻辑。当接口方法被调用时,会先传递给InvocationHandler,然后你可以在这里添加自定义行为。 ```java InvocationHandler handler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method call"); Object result = method.invoke(target, args); System.out.println("After method call"); return result; } }; ``` 3. **创建代理对象**:使用`Proxy.newProxyInstance()`方法,传入接口、InvocationHandler实例以及目标对象(如果有的话),返回一个新的代理对象。 ```java MyInterface target = ...; // 实现MyInterface的对象 MyInterface proxy = (MyInterface) Proxy.newProxyInstance( MyInterface.class.getClassLoader(), new Class[]{MyInterface.class}, handler ); ``` 4. **使用代理对象**:现在你可以像使用普通接口一样,调用代理对象的方法了,实际上会触发InvocationHandler的`invoke`方法。 ```java proxy.doSomething(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值