23种设计模式之代理模式
2017-09-12 14:48
369 查看
代理模式:即Proxy Pattern,23种常用的面向对象软件的设计模式之一。
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式能够解决什么问题呢?
1、监听被代理的类里面的方法什么时候执行
2、动态的给某一个方法添加新的功能
代理模式分类:
静态代理
能够使用静态代理首先得有一个前提条件:被代理的类必须要实现接口。
实现步骤:
(1)、首先要被代理类要实现接口
(2)、代理类必须要和 被代理的类实现相同的接口
(3)、在我们的代理类中实例化我们的被代理类的对象
(4)、重写接口中的方法
(5)、在我们调用被代理类中的方法的时候 可以进行拓展了
接口类 IUserDao.java
被代理类:UserDao.java
代理类:UserDaoProxy
动态代理
动态代理 又名JDK代理,也就是说这种代理模式是在JDK中提供了相应的实现类。动态代理的原理生成了子类的对象,可以避免静态代理中代理类接口过多的问题。
动态代理也有一个前提:就是我们被代理的类也要实现接口(或者本身就是接口)。
代码实现
接口和被代理类和上面的一样
测试类:Test.java
cglib代理
这种代理方式需要导入包
cglib-2.2.2.jar
asm-3.3.1.jar
UserDao.java
UserDaoProxy.java
还可以写成这样
测试类
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式能够解决什么问题呢?
1、监听被代理的类里面的方法什么时候执行
2、动态的给某一个方法添加新的功能
代理模式分类:
静态代理
能够使用静态代理首先得有一个前提条件:被代理的类必须要实现接口。
实现步骤:
(1)、首先要被代理类要实现接口
(2)、代理类必须要和 被代理的类实现相同的接口
(3)、在我们的代理类中实例化我们的被代理类的对象
(4)、重写接口中的方法
(5)、在我们调用被代理类中的方法的时候 可以进行拓展了
接口类 IUserDao.java
public interface IUserDao { public void method1(); }
被代理类:UserDao.java
public class UserDao implements IUserDao { @Override public void method1() { // TODO Auto-generated method stub System.out.println("这是方法1"); } }
代理类:UserDaoProxy
public class UserDaoProxy implements IUserDao { private UserDao userDao; @Override public void method1() { // TODO Auto-generated method stub System.out.println("开启事物"); userDao.method1(); System.out.println("结束事物"); } public UserDaoProxy(UserDao userDao) { super(); this.userDao = userDao; } public UserDaoProxy() { this.userDao =new UserDao(); } }
动态代理
动态代理 又名JDK代理,也就是说这种代理模式是在JDK中提供了相应的实现类。动态代理的原理生成了子类的对象,可以避免静态代理中代理类接口过多的问题。
动态代理也有一个前提:就是我们被代理的类也要实现接口(或者本身就是接口)。
代码实现
接口和被代理类和上面的一样
测试类:Test.java
public static void main(String[] args) { // TODO Auto-generated method stub UserDao userDao=new UserDao(); //在JDk中提供了一个类 这个类 Proxy /** * 第一个参数:就是当前代理的类的class对象.getClassLoader * 第二个参数:如果被代理的是类 class对象.getInterfaces() * 第二个参数如果代理的是接口的话 那么应该这样写 new Class[]{代理接口.class} * 第三个参数:就是用来监听我们的代理类里面方法的执行的 */ IUserDao userDao2=(IUserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new InvocationHandler() { /** * 中断我们的方法的执行的 * 你可以这样理解 就是调用我们的被代理类里面的方法的时候会自动被拦截下来 你可以确定是否执行 * proxy:生成的代理对象 * method:当前你请求的方法(反射里面的) * args:这个就是你执行这个方法需要的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //申明一个返回值 Object returnValue=null; //下面就可以对你要监听的方法进行处理 //例如:判定我们执行的方法是不是method1()方法 String methodName=method.getName(); if("method1".equals(methodName)){ //是不是要在执行方法之前添加事务 System.out.println("打开事务"); //执行这个方法 第一个参数;就是被代理的这个对象 returnValue=method.invoke(userDao, args); //在方法执行之后 关闭事务 System.out.println("关闭事务"); }else{ //这个表示的是当前请求的不是save方法 //下面表示的是没有调用save这个方法 returnValue=method.invoke(userDao, args); } return returnValue; } }); //查看userDao2的结果 userDao2.method1(); }
cglib代理
这种代理方式需要导入包
cglib-2.2.2.jar
asm-3.3.1.jar
UserDao.java
public class UserDao { public void test(){ System.out.println("数据保存成功..."); } }
UserDaoProxy.java
public class UserDaoProxy { private UserDao userDao=null; public UserDaoProxy() { userDao=new UserDao(); } public UserDaoProxy(UserDao userDao) { this.userDao=userDao; } /* * 该方法返回被代理对象 */ public Object getObject() { //第一步:申明这个enhancer对象 Enhancer enhancer=new Enhancer(); //第二步:设置该代理类的对象的父类 enhancer.setSuperclass(userDao.getClass()); //设置监听父类里面的方法的回调 enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] arg2,MethodProxy arg3) throws Throwable { //获取方法名 String methodName = method.getName(); //设置返回的结果 Object returnValue=null; //判定是否是我们的监听的方法 if("test".equals(methodName)) { System.out.println("执行事务"); returnValue=method.invoke(userDao, arg2); System.out.println("结束事务"); }else { //如果不是,就直接放行 returnValue=method.invoke(userDao, arg2); } return returnValue; } }); return enhancer.create(); } }
还可以写成这样
public class UserDaoProxy implements MethodInterceptor{ private UserDao userDao=null; public UserDaoProxy() { userDao=new UserDao(); } public UserDaoProxy(UserDao userDao) { this.userDao=userDao; } public Object getObject() { //声明一个enhancer对象 Enhancer enhancer=new Enhancer(); //设置UserDao为该代理对象的父类 enhancer.setSuperclass(userDao.getClass()); //监听父类的方法 enhancer.setCallback(this); return enhancer.create(); } //监听方法 @Override public Object intercept(Object obj, Method method, Object[] arg2,MethodProxy arg3) throws Throwable { //获取方法名 String methodName = method.getName(); //返回结果 Object returnValue=null; //判定方法是否是我们监听的方法 if("test".equals(methodName)) { System.out.println("开始事务"); returnValue=method.invoke(userDao, arg2); System.out.println("结束事务"); }else{ returnValue=method.invoke(userDao, arg2); } return returnValue; }}
测试类
public static void main(String[] args) { // TODO Auto-generated method stub UserDaoProxy userDaoProxy=new UserDaoProxy(new UserDao()); UserDao userDao=(UserDao) userDaoProxy.getObject(); }
相关文章推荐
- Java23种设计模式之-----代理模式
- 【Unity与23种设计模式】代理模式(Proxy)
- 【23种设计模式从零学4-代理模式】
- Java23种设计模式——代理模式
- 23种设计模式(17):代理模式
- 23种设计模式(19):代理模式
- 【23种设计模式】结构型模式 > 代理模式
- java_23种设计模式之代理模式
- Java 23种设计模式之代理模式
- 23种设计模式-----代理模式(proxy)
- c++23种设计模式之代理模式
- 23种设计模式--代理模式
- 23种设计模式之代理模式
- java23种设计模式 代理模式(五)
- 23种设计模式(6):代理模式
- 【23种设计模式】之 代理模式(Representative Pattern)
- 23种设计模式之代理模式
- 【Unity与23种设计模式】代理模式(Proxy)
- GoF23种设计模式之结构型模式之代理模式
- 23种设计模式----------代理模式(一)