设计模式-代理模式

本文介绍了静态代理模式,如Java中的静态代理,通过接口或父类实现目标对象的功能扩展,包括了UML类图和代码示例。接着探讨了动态代理,特别是JDK代理(基于接口)和Cglib代理(针对无接口对象),并提供了相应的代码和优缺点分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代理模式

静态代理

基本介绍:

静态代理在使用中,需要定义接口或者父类,被代理对象(目标对象)与代理对象一起实现相同的接口或者是继承相同的父类。

实例:

uml类图:

代码:

ITeacherDao:

 public interface ITeacherDao {
     /**
      * teach方法
      */
     void teach();
 }
 ​

TeacherDaoImpl:

 public class TeacherDaoImpl implements ITeacherDao {
     @Override
     public void teach() {
         System.out.println("teacher is working");
 ​
     }
 }
 ​

TeacherDaoProxy :

 public class TeacherDaoProxy implements ITeacherDao {
 ​
     //    目标对象 通过接口来聚合
     /**
      * target
      */
     private final ITeacherDao target;
     public TeacherDaoProxy(ITeacherDao target){
         this.target=target;
     }
 ​
     @Override
     public void teach() {
         System.out.println("proxy is working");
         //目标的核心代码
         target.teach();
         System.out.println("proxy is over");
     }
 }
 ​

client:

  @Test
     public void test1(){
         TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy( new TeacherDaoImpl());
         teacherDaoProxy.teach();
     }

优点:在不修改目标对象功能的情况下,能通过代理对象对目标功能进行扩展

缺点:

  1. 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类

  2. 一旦接口增加方法,目标对象和代理对象都要维护

动态代理

基本介绍:

  1. 代理对象,不需要实现接口,但是目标对象要实现接口,否者不能用动态代理

  2. 代理对象的生成,利用jdk的API,动态的在内存中构建代理对象

  3. 动态代理也叫做:JDK代理,接口代理

UML图:

代码:

ITeacherDao:

 public interface ITeacherDao {
     /**
      * teach方法
      */
     void teach();
 ​
     /**
      *
      * @param a a
      * @param b b
      * @return int
      */
     int count(int a,int b);
 }
 ​

TeacherDaoImpl:

 public class TeacherDaoImpl implements ITeacherDao {
     @Override
     public void teach() {
         System.out.println("teacher is working");
 ​
     }
 ​
     @Override
     public int count(int a, int b) {
         System.out.println("开始计算");
         return a+b;
     }
 }

ProxyFactory:

 public class ProxyFactory {
     private Object target;
 ​
     public ProxyFactory(Object target){
         this.target=target;
     }
     public Object getProxyInstance(){
         return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 System.out.println("JDK代理开始");
                 Object returnVal = method.invoke(target, args);
                 System.out.println("jdk动态代理结束");
                 return returnVal;
             }
         });
     }
 ​
 }

client:

  @Test void Test3(){
         //创建目标对象
         ITeacherDao teacherDao = new TeacherDaoImpl();
         //给目标对象创建代理对象
         ITeacherDao  teacher=(ITeacherDao ) new ProxyFactory(teacherDao).getProxyInstance();
         teacher.teach();
         int a=teacher.count(2,5);
         System.out.println(a);
     }

cglib代理

  1. 静态代理和jDK代理模式都要求目标对象实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理-这就是cglib代理。

  2. Cglib代理也叫做子类代理,他是在内存中构建一个子类对象从而实现目标对象功能扩展,cglib代理也可以归类到动态代理

  3. Cglib代理是一个强大的高性能的代码生成包,它可以在运行期间扩展java类与实现java的接口,他广泛的被许多AOP框架使用,例如Spring AOP,实现方法拦截

  4. 在AOP编程中如何选择代理模式: a. 目标对象需要实现接口,用JDK代理

    b. 目标对象不需要实现接口,用Cglib代理

  5. Cglib包底层是通过使用字节码处理框架ASM来转换字节码生成新的类

UML图:

代码:

Teacher:

 public class Teacher {
     public void teach() {
         System.out.println("teacher is working");
     }
 ​
     public Integer count(int a,int b){
         return a+b;
     }
 }

ProxyFactory:

 public class ProxyFactory implements MethodInterceptor {
 ​
     //维护一个目标对象
     private  Object target;
 ​
     public ProxyFactory(Object target){
         this.target=target;
     }
 ​
     //返回一个代理对象,是target的代理对象
 ​
     /**
      *
      * @return Object
      */
     public Object getProxyInstance(){
         //创建一个工具类
         Enhancer enhancer=new Enhancer();
         //设置父类
         enhancer.setSuperclass(target.getClass());
         //设置回调函数
         enhancer.setCallback(this);
         //创建子类对象,及代理对象
         return enhancer.create();
     }
 ​
     // 重写
     @Override
     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
         System.out.println("cglib代理开始");
         Object re = method.invoke(target, objects);
         System.out.println("cglib提交");
         return re;
     }
 }

client:

  @Test
     void test3(){
         //
         Teacher target=new Teacher();
         ProxyFactory proxyFactory=new ProxyFactory(target);
         Teacher teacher = (Teacher) proxyFactory.getProxyInstance();
         teacher.teach();
         System.out.println(teacher.count(4,5));
 ​
     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值