`
qindongliang1922
  • 浏览: 2152489 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116483
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124716
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58722
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70512
社区版块
存档分类
最新评论

JAVA之JDK动态代理

    博客分类:
  • JAVA
阅读更多
在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和接口,可以生成JDK动态代理类或动态代理对象。

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

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

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


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

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

package com.qin.aop;

/**
 * 通用的模拟AOP
 * 切面类,其方法可以在运行时被调入
 * 
 * **/
public class DogUtils {
	
/**
 * 
 * 第一个拦截器的方法
 * 
 * **/
	public void method1(){
		
		System.out.println("=======模拟第一个通用的方法==========");
		
	}
	
	
	/**
	 * 
	 * 第一个拦截器的方法
	 * 
	 * **/
		public void method2(){
			
			System.out.println("=======模拟第二个通用的方法==========");
			
		}
	
	

}



Dog接口,JDK动态代理只能给接口生成代理。
package com.qin.proxy;

/***
 * 
 * 定义Dog接口
 * */
public interface Dog {

	/**
	 * 
	 * 详细信息的方法
	 * **/
public 	void info();
	
	
	/**
	 * 运行的方法 
	 * 
	 * */
public	void run();
	
	
	
	
	
}


package com.qin.proxy.impl;

import com.qin.proxy.Dog;

/**
 * 
 * 实现类
 * **/
public class GunDog implements Dog {

	@Override
	public void info() {
		System.out.println("我是一只猎狗!  ");
		
	}

	@Override
	public void run() {
		
		System.out.println("我奔跑迅速!");
		
	}

	
	
	
	
}



package com.qin.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import com.qin.aop.DogUtils;

 

/**
 * 动态代理的实现自定义类
 * 
 * 
 * **/
public class MyInvokationHandler  implements InvocationHandler{

	/*
	 * 需要被代理的对象
	 * **/
	private Object obj;
	
	
	
	 
	public void setObj(Object obj) {
		this.obj = obj;
	}




	/**
	 * 执行动态代理对象的所有方法时,
	 * 都会被替换成如下的invoke方法
	 * 
	 * ***/
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
	 DogUtils du=new DogUtils();
	 //执行DogUtils对象中的method1方法
	 du.method1();
	 //以target作为主调来执行method方法
	 Object  result=method.invoke(obj, args);
	 du.method2();
		return result;
	}

	 

	
	
}



package com.qin.proxy;

import java.lang.reflect.Proxy;


/**
 * 该对象为指定的target生成动态代理实例
 * 
 * **/
public class MyProxyFactory  {
	
	public static Object getProxy(Object obj){
		
		//创建一个MyInvokationHandler对象
		MyInvokationHandler hadler=new MyInvokationHandler();
		
		hadler.setObj(obj);
		//创建并返回一个动态代理
		
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), hadler);
		
	} 
	

}


测试:
package com.qin.test;

import com.qin.proxy.Dog;
import com.qin.proxy.MyProxyFactory;
import com.qin.proxy.impl.GunDog;

/**
 * 
 *  测试驱动类
 * **/
public class Test {

	
	
	
	public static void main(String[] args) {
		Dog target=new GunDog();
		  
		Dog dog=(Dog)MyProxyFactory.getProxy(target);
		 
		dog.info();
		dog.run();
		
		
	}
	
}


结果输出如下:

=======模拟第一个通用的方法==========
我是一只猎狗!  
=======模拟第二个通用的方法==========
=======模拟第一个通用的方法==========
我奔跑迅速!
=======模拟第二个通用的方法==========


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics