设计模式(6)代理模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34645958/article/details/82047882

1.什么是代理模式

   编程中有一个思想就是不要随意修改别人的代码,如果需要修改,可以通过代理模式来实现

   用户------代理对象--------目标对象(被代理对象)

2.静态代理

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

  缺点:代理对象和目标对象需要实现同一个接口,所以一旦增加接口中的方法,代理对象和目标对象都需要修改

//接口
public interface IUser {
    void say();
}

//目标对象
public class User implements IUser{

    @Override
    public void say() {
        System.out.println("target Object...");
    }
}

//代理对象
public class UserProxy implements IUser {
    //保存目标对象
    private User target;

    public UserProxy(User target){
        this.target = target;
    }
    @Override
    public void say() {
        System.out.println("add Proxy Object...");
        target.say();
    }
}

//测试类
public class Test {
    public static void main(String[] args) {
        //目标对象
        User target = new User();
        //代理对象
        UserProxy proxy = new UserProxy(target);

        proxy.say();
    }
}

 

 

3.动态代理(JDK代理)

利用JDK的API,动态的在内存中构建代理对象(java.lang.reflect.Proxy)

缺点:代理对象虽然不需要实现接口,但是目标对象需要实现接口,否则不能用动态代理

//创建动态代理对象
//(动态代理对象不需要实现接口,但需要指定接口的类型)
public class ProxyFactory {

    //维护一个目标对象
    private Object target;
    public ProxyFactory(Object target){
        this.target = target;
    }

    //给目标对象生成代理对象
    public Object getProxyInstance(){
        //ClassLoader:指定目标对象的类加载器
        //Class<?>[]:目标对象的接口类型
        //InvocationHandler:事件处理器,执行目标对象方法时,会触发事件处理器方法
        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("add proxy...");
                        //执行目标对象方法
                        Object returnValue = method.invoke(target, args);
                        return returnValue;

                    }
                });

    }
}
public class Test {
    public static void main(String[] args) {
        //目标对象
        User target = new User();

        //给目标对象创建代理对象
        IUser proxy = (IUser)new ProxyFactory(target).getProxyInstance();
        proxy.say();
    }

}

4.Cglib代理

(1)以目标代理对象子类的方式实现代理,这种方法叫Cglib代理(底层是对字节码处理框架ASM来转换字节码并生成新的类)

(2)实现方法:首先要引入cglib的jar包,spring核心包中已包含cglib功能,所以引入spring核心包即可

     在Spring的AOP编程中:
          如果加入容器的目标对象有实现接口,用JDK代理
          如果目标对象没有实现接口,用Cglib代理

//目标对象,不需要实现接口
public class User {
    public void say(){
        System.out.println("aim object...");
    }
}

//代理类
public class ProxyFactory implements MethodInterceptor {

    //维护目标对象
    private Object target;
    public ProxyFactory(Object target){
        this.target = target;
    }

    //给目标对象创建一个代理对象
    public Object getProxyInstance(){
        //1.工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(target.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类(代理对象)
        return enhancer.create();

    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("增强方法...");
        //执行目标对象的方法
        Object returnValue = method.invoke(target, objects);
        return returnValue;
    }
}

//测试类
public class Test {


    public static void main(String[] args) {
        //目标对象
        User target = new User();
        //代理对象
        User proxy = (User) new ProxyFactory(target).getProxyInstance();

        //执行代理对象的方法
        proxy.say();
    }

}

                   

  

猜你喜欢

转载自blog.csdn.net/qq_34645958/article/details/82047882