java实现简单的动态代理
来源:互联网 发布:ubuntu光盘安装教程 编辑:程序博客网 时间:2024/05/16 06:54
Java实现简单的动态代理
先写一个简单的例子来说明为什么需要代理。
1.编写接口UserManager.java
package proxy;public interface UserManager {public void addUser(int id, String name, int age);public void deleteUser(int id);public String getUserName(int id);}
2.编写实现类UserManagerImpl.java
package proxy;public class UserManagerImpl implements UserManager {@Overridepublic void addUser(int id, String name, int age) {System.out.println("------------addUser()-----------");}@Overridepublic void deleteUser(int id) {System.out.println("------------deleteUser()-----------");}@Overridepublic String getUserName(int id) {System.out.println("------------getUserName()-----------");return null;}}3.编写客户端类Client.java对UserManager实现进行测试。
package proxy;public class Client {public static void main(String[] args) {// TODO Auto-generated method stubUserManager manager = new UserManagerImpl();manager.addUser(1, "zhangsan", 24);}}输出结果为------------addUser()-----------
现在,想在所有UserManager函数调用之前,先对用户信息进行安全性检查,就需要在所有的函数执行前添加安全性检查,如代码UserManagerImpl.java所示。
package proxy;public class UserManagerImpl implements UserManager {@Overridepublic void addUser(int id, String name, int age) {security();System.out.println("------------addUser()-----------");}@Overridepublic void deleteUser(int id) {security();System.out.println("------------deleteUser()-----------");}@Overridepublic String getUserName(int id) {security();System.out.println("------------getUserName()-----------");return null;}private void security(){System.out.println("------------security()--------------");}}这样实现会打破程序设计的封装性,如果需要添加功能就需要需改程序的源代码,因此这里就需要使用代理的思想。
增加一个代理,代理类可以控制原对象,所以在调用原对象之前就可以进行安全性检查。
添加代理类UserManagerImplProxy.java
package proxy;public class UserManagerImplProxy implements UserManager {private UserManager manager;public UserManagerImplProxy(UserManager manager){this.manager = manager;}@Overridepublic void addUser(int id, String name, int age) {security();this.manager.addUser(id, name, age);}@Overridepublic void deleteUser(int id) {security();this.manager.deleteUser(id);}@Overridepublic String getUserName(int id) {security();return this.manager.getUserName(id);}private void security(){System.out.println("------------security()--------------");}}
将实际对象通过构造函数传递给代理类,在调用实际对象方法前添加对安全性的检查security()方法,通过使用代理将需要添加的功能从UserMangerImpl类中分离出来
修改后的Client.java代码如下。
package proxy;public class Client {public static void main(String[] args) {// TODO Auto-generated method stub//UserManager manager = new UserManagerImpl();//manager.addUser(1, "zhangsan", 24);UserManager manager = new UserManagerImplProxy(new UserManagerImpl());manager.addUser(1, "zhangsan", 24);}}程序输出为------------security()--------------
------------addUser()-----------
代理模式:在实际开发当中使用频率非常高的一种设计模式。
定义:为其他对象提供一种代理机制以控制这个对象的访问。
代理对象要与目标对象的接口一致。
以上是简单代理的实现方式,在实际使用中,使用最多的是动态代理。代理对象会在运行期生成。
编写安全性检查的处理方法类SecurityHandler.java
package proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class SecurityHandler implements InvocationHandler {private Object targerObject;public Object newProxyObject(Object targetObject){this.targerObject = targetObject;Object object = Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),<span style="white-space:pre"></span>targetObject.getClass().getInterfaces(),this);return object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {security();Object result = null;try{result = method.invoke(this.targerObject, args);}catch(Exception e){e.printStackTrace();}return result;}private void security(){System.out.println("------------security()--------------");}}下面对动态代理的实现进行说明
1.需要实现InvocationHandler接口,并实现这个接口当中的invoke方法。当调用代理对象的方法的时会自动调用invoke方法,所以可以将安全性检查的方法放到invoke方法中,这样在调用目标对象的方法前就会调用security()方法了。
2.在SecurityHandler方法中声明了一个Object类型的实例变量,用来存储目标对象。
3.编写newProxyObject方法,这个方法将目标对象赋值给实例变量targerObject来保存目标对象。
4.调用Proxy的newProxyInstance函数来创建一个代理对象,该函数有3个参数,分别是ClassLoader,接口数组(Class<?>[])以及一个InvocationHandler。
JVM在加载类的时候就是通过调用ClassLoader的loadClass()方法来加载类的,而第二个参数是一个接口数组,这就是说明被代理的类需要实现某个接口,当然也可以不实现接口,使用CGLIB技术,这个技术不在本文讨论范围内。第三个参数是一个InvocationHandler,这里置为this即可。
修改Client.java
package proxy;public class Client {public static void main(String[] args) {// TODO Auto-generated method stub//UserManager manager = new UserManagerImpl();//manager.addUser(1, "zhangsan", 24);//UserManager manager = new UserManagerImplProxy(new UserManagerImpl());//manager.addUser(1, "zhangsan", 24);SecurityHandler proxy = new SecurityHandler();<span style="white-space:pre"></span>UserManager manager = (UserManager)proxy.newProxyObject(new UserManagerImpl());<span style="white-space:pre"></span>manager.addUser(1, "zhangsan", 24);}}
程序输出为------------security()--------------
------------addUser()-----------
创建一个SecurityHandler对象,然后创建一个目标对象,调用newProxyObject函数获得这个对象的一个代理对象,再调用代理对象的方法,这样即可实现动态代理。
0 0
- java动态代理的简单实现:
- java实现简单的动态代理
- Java静态代理和动态代理的简单代码实现。
- Java动态代理简单实现
- 实现简单的动态代理!
- 实现简单的动态代理!
- 动态代理的简单实现
- 动态代理的简单实现
- 实现简单的动态代理
- JAVA动态代理实现aop的简单例子
- 关于在JAVA中如何实现简单的动态代理
- 使用Java动态代理实现简单AOP
- 动态代理的实现1-简单实现
- 动态代理的实现1-简单实现
- 动态代理的实现1-简单实现
- Java动态代理的实现
- Java动态代理的实现
- Java动态代理的实现
- hdu 1081 & poj 1050 To The Max(最大和的子矩阵)
- 我的第一篇博客
- UIImagePickerController获取图片名
- cocos2dx 3.0 js继承:John Resiq的继承写法解析
- 『ANDROID』Android学习与记录
- java实现简单的动态代理
- 【Android】 Android开发优化之——从代码角度进行优化
- web.xml文件的作用
- iOS开发-Xcode5创建静态库详解(Cocoa Touch Static Library)
- 彻底退出android程序的方法
- mysql transaction
- Android中通过GPS或NetWork获取当前位置的经纬度
- Linux shell 命令 split
- 【Android】 Android开发优化之——使用软引用和弱引用