码迷,mamicode.com
首页 > 编程语言 > 详细

java动态代理(JDK和cglib)

时间:2015-05-25 18:52:09      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:java   jdk   反射机制   动态代理   cglib   

JAVA反射机制
JAVA反射机制在运行状态中,对于任意一个,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
JAVA的动态代理 
代理模式 
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 
按照代理的创建时期,代理类可以分为两种。 
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 
动态代理:在程序运行时,运用反射机制动态创建而成。
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
pom.xml引入相关jar
	<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>3.1</version>
		</dependency>

代码
package com.eyugame.test.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * jdk自带动态代理
 * @author JYC506
 *
 */
public class JDKProxy implements InvocationHandler {

	private Object target;

	/**
	 * 绑定委托对象并返回一个代理类
	 * 
	 * @param T
	 *            要代理的类
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	@SuppressWarnings("unchecked")
	public <superClazz> superClazz getInstance(Class<?> T,Class<?> superClazz) throws InstantiationException, IllegalAccessException {
		this.target = T.newInstance();
		// 取得代理对象
		return (superClazz) Proxy.newProxyInstance(T.getClassLoader(), T.getInterfaces(), this); // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
	}

	/**
	 * 绑定委托对象并返回一个代理类
	 * 
	 * @param T
	 *            要代理的类
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	@SuppressWarnings("unchecked")
	public <superClazz> superClazz getInstance(Object target ,Class<?> superClazz) {
		this.target =target;
		Class<?> clazz=this.target.getClass();
		// 取得代理对象
		return (superClazz) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(), this); // 要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
	}
	/**
    * 
    */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = null;
		System.out.println("事物开始");
		result = method.invoke(target, args);
		System.out.println("事物结束");
		return result;
	}
	
	public static void main(String[] args) {
		JDKProxy proxy = new JDKProxy();
		Idog dog1 = null;
		Idog dog2=new Dog();
	
		try {
			dog1 = proxy.getInstance(Dog.class,Idog.class);
			dog2=proxy.getInstance(new Dog(),Idog.class);
			dog1.doSomething();
			dog2.setId(23);
			System.out.println(dog2.getId());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class Dog implements Idog {
    private int id;
    
	public void doSomething() {
		System.out.println("call doSomething()");
	}

	@Override
	public void setId(int id) {
	this.id=id;
		
	}

	@Override
	public int getId() {
	return this.id;
	}


}

interface Idog {
	
	void doSomething();
	
	void setId(int id);
	
	int getId();
}
运行结果
技术分享
package com.eyugame.test.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * cglib动态代理
 * @author JYC506
 *
 */
public class CglibProxy implements MethodInterceptor {

	/**
	 * 创建代理对象
	 * 
	 * @param target
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getInstance(Class<?> T) {
		
		Enhancer enhancer = new Enhancer();
		/* 指定父类 */
		enhancer.setSuperclass(T);
		// 回调方法
		enhancer.setCallback(this);
		// 创建代理对象
		return (T)enhancer.create();
	}

	@Override
	// 回调方法
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		System.out.println("事物开始");
		Object o = proxy.invokeSuper(obj, args);
		System.out.println("事物结束");
		return o;
	}

	public static void main(String[] args) {
		CglibProxy proxy = new CglibProxy();
		People people = proxy.getInstance(People.class);
		people.setId(23);
		System.out.println(people.getId());
	}

}

class People {
	
	private int id;
	
	private String username;
	
	private int age;

	public int getId() {
		System.out.println("获取id");
		return id;
	}

	public void setId(int id) {
		System.out.println("给id赋值");
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

技术分享

java动态代理(JDK和cglib)

标签:java   jdk   反射机制   动态代理   cglib   

原文地址:http://blog.csdn.net/h348592532/article/details/45971237

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!