设计模式---代理模式(Proxy)

代理模式:为一个对象提供一个替身,以控制这个对象的访问。即通过代理对象访问目标对象。好处:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

被代理的对象可以是远程对象创建开销大的对象或者需要安全控制的对象

代理模式有不同的形式,主要有静态代理动态代理(JDK代理、接口代理)Cglib代理(可以在内存动态创建对象,无需实现接口,属于动态代理)

一、静态代理

1、静态代理模式的基本介绍

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

2、具体实现

说明:老师病假,请其他老师替代上课

  1. 定义一个接口:ITeacherDao
  2. 目标对象TeacherDao(生病的老师,被代理对象)实现接口ITeacherDao
  3. 使用静态代理方式,就需要在代理对象TeacherDAOProxy中也实现ITeacherDao
  4. 调用的时候通过调用代理对象的方法来调用目标对象
  5. 特别提醒:代理对象与目标对象要实现相同的接口,然后通过调用相同的方法来调用目标对象的方法
package com.lfh.proxy;

public interface ITeacher {
    void teacher();
}
package com.lfh.proxy;

public class TeacherDAO implements ITeacher{
    @Override
    public void teacher() {
        System.out.println("老师授课中");
    }
}
package com.lfh.proxy;

public class TeacherDaoProxy implements ITeacher {
    private ITeacher target;

    public TeacherDaoProxy(ITeacher target) {
        this.target = target;
    }

    @Override
    public void teacher() {
        System.out.println("代理开始");
        target.teacher();
        System.out.println("代理结束");
    }
}
package com.lfh.proxy;

public class ProxyTest {
    public static void main(String[] args) {
        TeacherDAO teacherDAO= new TeacherDAO();
        TeacherDaoProxy proxy=new TeacherDaoProxy(teacherDAO);
        proxy.teacher();
    }

}

3、静态代理优缺点:

优点:在不修改目标对象的基础上,通过代理对象对目标功能扩展

缺点:代理对象需要和目标对象实现一样的接口,所有有很多代理类一旦接口增加方法,目标对象和代理对象都需要维护

二、动态代理

1、代理对象的基本介绍

  1. 代理对象,不需要实现接口,但是目标对象要实现接口,否则不能使用动态代理
  2. 代理对象的生成,时利用jdk类的api,动态在内存中构建代理对象
  3. 动态代理也叫做:jdk代理、接口代理

2、代码实现

package com.lfh.dynamicproxy;

public interface ITeacher {
    void teacher();
}
package com.lfh.dynamicproxy;

public class TeacherDAO implements ITeacher {
    @Override
    public void teacher() {
        System.out.println("老师授课中");
    }
}
package com.lfh.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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 invoke = method.invoke(target, args);
                return invoke;
            }
        });
    }
}
package com.lfh.dynamicproxy;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class test {
    public static void main(String[] args) {
        TeacherDAO teacherDAO = new TeacherDAO();
        ProxyFactory proxyFactory = new ProxyFactory(teacherDAO);
        ITeacher proxyInstance = (ITeacher)proxyFactory.getProxyInstance();
        System.out.println(proxyInstance);
        proxyInstance.teacher();
    }
}

三、Cglib代理

1、Cglib基本介绍

  1. 静态代理和jdk代理都要求目标对象实现一个接口,但是有时目标对象只是单独一个对象,并没有实现任何的接口。使用目标对象子类实现代理,这就是Cglib代理。
  2. Cglib代理也叫做子类代理,他在内存中构建一个子类对象从而实现对目标对象功能扩展。
  3. Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口,它广泛被AOP框架使用,Spring AOP,实现方法拦截
  4. AOP中如何选择代理模式
    • 目标对象需要实现接口,JDK代理
    • 目标对象不需要实现接口,Cglib代理
  5. Cglib底层是通过使用字节码处理框架ASM来转换字节码并生成新的类

注意:目标对象不能为finall(无法被继承)、static

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页