java原生动态代理实现demo
2014-08-27 11:14
405 查看
这只是一个demo试验,理论性的只是较少;
1,建立数据bean:User.java
2,建服务层接口(目标类必须实现接口):IPersonService.java
save方法执行前..
新增用户:kalven
save方法执行后...
update方法执行前..
更新用户:kalven
update方法执行后...
delete方法执行前..
删除用户Id:1
delete方法执行后...
8,结果分析总结:
从输出结果可以看到对目标类中的方法的调用都被拦截到ProxyHandle.java类中的方法invoke中去了;实现动态代理的关键类是Proxy和接口InvocationHandler;
9,对生成的动态代理类分析:
将第六步的测试类修改一下:
可以对该文件进行反编译查看生成的代理类的内容:
10,总结:
诚然,Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。有很多条理由,人们可以否定对
class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例。
1,建立数据bean:User.java
/** * User.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.bean; /** * <p> * ClassName: User *</p> * <p> * Description: TODO * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public class User { private Integer id; // 用户Id private String userName; //用户名 private String passWord; //密码 public User() { super(); } public User(Integer id, String userName, String passWord) { super(); this.id = id; this.userName = userName; this.passWord = passWord; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } }
2,建服务层接口(目标类必须实现接口):IPersonService.java
/** * IPersonService.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.service; import com.mfy.test.proxy.bean.User; /** * <p> * ClassName: IPersonService *</p> * <p> * Description: TODO * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public interface IUserService { void save(User user); void update(User user); void delete(Integer id); }<strong> </strong>3,服务层实现类:UserServiceImp.java
/** * UserServiceImp.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.service.imp; import com.mfy.test.proxy.bean.User; import com.mfy.test.proxy.service.IUserService; /** * <p> * ClassName: UserServiceImp *</p> * <p> * Description: TODO * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public class UserServiceImp implements IUserService { @Override public void save(User user) { // TODO Auto-generated method stub System.out.println("新增用户:" + user.getUserName()); } @Override public void update(User user) { // TODO Auto-generated method stub System.out.println("更新用户:" + user.getUserName()); } @Override public void delete(Integer id) { // TODO Auto-generated method stub System.out.println("删除用户Id:" + id); } }4,目标方法拦截处理实现类:ProxyHandle.java
/** * ProxyHandle.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.handle; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * <p> * ClassName: ProxyHandle *</p> * <p> * Description: 代理拦截处理类 * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public class ProxyHandle implements InvocationHandler { private Object target; public ProxyHandle(Object target) { this.target = target; } /* (non-Javadoc) * <p>Title: invoke</p> * <p>Description: 在该方法中对目标类方法调用的处理 </p> * @param proxy * @param method * @param args * @return * @throws Throwable * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println(method.getName() + "方法执行前.."); Object result = method.invoke(target, args); System.out.println(method.getName() + "方法执行后..."); return result; } }5:,动态代理类生产器:ProxyFactory.java
/** * ProxyFactory.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.handle; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * <p> * ClassName: ProxyFactory *</p> * <p> * Description: TODO * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public class ProxyFactory { public static Object createProxyObj (Class targetInterface,InvocationHandler h) throws Exception { return Proxy.newProxyInstance(targetInterface.getClassLoader(), new Class[]{targetInterface}, h); } }6,测试类:TestMain.java
/** * TestMain.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.main; import com.mfy.test.proxy.bean.User; import com.mfy.test.proxy.handle.ProxyFactory; import com.mfy.test.proxy.handle.ProxyHandle; import com.mfy.test.proxy.service.IUserService; import com.mfy.test.proxy.service.imp.UserServiceImp; /** * <p> * ClassName: TestMain *</p> * <p> * Description: TODO * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public class TestMain { public static void main(String[] args) throws Exception { User user = new User(1,"kalven","11111111"); IUserService serviceProxy = (IUserService)ProxyFactory.createProxyObj(IUserService.class, new ProxyHandle(new UserServiceImp())); serviceProxy.save(user); System.out.println(); serviceProxy.update(user); System.out.println(); serviceProxy.delete(user.getId()); } }7,输出结果:
save方法执行前..
新增用户:kalven
save方法执行后...
update方法执行前..
更新用户:kalven
update方法执行后...
delete方法执行前..
删除用户Id:1
delete方法执行后...
8,结果分析总结:
从输出结果可以看到对目标类中的方法的调用都被拦截到ProxyHandle.java类中的方法invoke中去了;实现动态代理的关键类是Proxy和接口InvocationHandler;
9,对生成的动态代理类分析:
将第六步的测试类修改一下:
/** * TestMain.java * Created at 2014年8月27日 * Created by mengfanyuan * Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved. */ package com.mfy.test.proxy.main; import java.io.FileNotFoundException; import java.io.FileOutputStream; import sun.misc.ProxyGenerator; import com.mfy.test.proxy.bean.User; import com.mfy.test.proxy.handle.ProxyFactory; import com.mfy.test.proxy.handle.ProxyHandle; import com.mfy.test.proxy.service.IUserService; import com.mfy.test.proxy.service.imp.UserServiceImp; /** * <p> * ClassName: TestMain *</p> * <p> * Description: TODO * </p> * <p> * Author: mengfanyuan * Email:kalvenmeng@163.com * </p> * <p> * Date: 2014年8月27日 * </p> */ public class TestMain { public static void main(String[] args) throws Exception { User user = new User(1,"kalven","11111111"); IUserService serviceProxy = (IUserService)ProxyFactory.createProxyObj(IUserService.class, new ProxyHandle(new UserServiceImp())); serviceProxy.save(user); System.out.println(); serviceProxy.update(user); System.out.println(); serviceProxy.delete(user.getId()); createProxyClassFile(); } public static void createProxyClassFile() throws Exception{ String fileName = "UserServiceProxy"; byte[] date = ProxyGenerator.generateProxyClass(fileName, new Class[]{IUserService.class}); FileOutputStream out = new FileOutputStream(fileName + ".class"); out.write(date); out.close(); } }执行完毕后可以在工程根路径下找到文件:UserServiceProxy.class
可以对该文件进行反编译查看生成的代理类的内容:
import com.mfy.test.proxy.bean.User; import com.mfy.test.proxy.service.IUserService; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; public final class UserServiceProxy extends Proxy implements IUserService { private static Method m1; private static Method m5; private static Method m4; private static Method m0; private static Method m3; private static Method m2; public UserServiceProxy(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final boolean equals(Object paramObject) throws { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void update(User paramUser) throws { try { this.h.invoke(this, m5, new Object[] { paramUser }); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void delete(Integer paramInteger) throws { try { this.h.invoke(this, m4, new Object[] { paramInteger }); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() throws { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void save(User paramUser) throws { try { this.h.invoke(this, m3, new Object[] { paramUser }); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() throws { try { return (String)this.h.invoke(this, m2, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m5 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("update", new Class[] { Class.forName("com.mfy.test.proxy.bean.User") }); m4 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("delete", new Class[] { Class.forName("java.lang.Integer") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("save", new Class[] { Class.forName("com.mfy.test.proxy.bean.User") }); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } } }
10,总结:
诚然,Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。有很多条理由,人们可以否定对
class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例。
相关文章推荐
- Core Java:使用java.lang.reflect实现JDK动态代理的小DEMO
- AOP系列之三:用Java动态代理实现AOP [zz]
- AOP初学者第一步:用Java动态代理实现AOP
- 使用JAVA中的动态代理实现数据库连接池
- Java动态代理实现
- 用Java动态代理实现AOP
- 使用JAVA中的动态代理实现数据库连接池
- 用Java动态代理实现AOP
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP(转)
- Java动态代理实现AOP
- 使用JAVA中的动态代理实现数据库连接池
- 使用JAVA中的动态代理实现数据库连接池 Z
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- 使用JAVA中的动态代理实现数据库连接池
- 使用Java动态代理实现AOP
- 用Java动态代理实现AOP
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- Java初学者如何迈出AOP第一步--使用Java 动态代理实现AOP
- Java动态代理实现AOP
- Java动态代理实现