java动态代理(JDK和cglib)

来源:互联网 发布:网络小三毛图片 编辑:程序博客网 时间:2024/06/06 09:01
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()");}@Overridepublic void setId(int id) {this.id=id;}@Overridepublic 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;}}


2 0