java设计模式之责任链模式讲解 (java设计模式实现多渠道支付)

代理模式

JAVA设计代理模式应用场景,java设计的代理模式设计案例

一、代理模式作用

业务逻辑上线使用后,如果还有一些另外的与原本逻辑无关的需求,并且尽量不要改动原本的调用方式,可以采用代理模式来进行原本业务功能的增强。

二、代理模式实现要素

1、要有代理类和被代理类

2、代理类和被代理类实现相同的接口

3、代理类要依赖被代理类,因为需要被代理类来实现业务逻辑

JAVA设计代理模式应用场景,java设计的代理模式设计案例

三、静态代理

下面,我们就用代码的方式来展现静态代理模式的使用方式:

/**
 * 简单接口
 */
public interface Hello {
    public void sayHello();
}
/**
 * 简单接口的实现类
 */
class HelloImpl implements Hello {
    @Override
    public void sayHello() {
        System.out.println("hello, world");
    }
}
/**
 * 代理类,类中注入被代理对象,并进行功能的增强
 */
class HelloImplProxy implements Hello {
    //被代理对象
    private Hello target ;
    
    //通过构造器注入被代理对象
    public HelloImplProxy(Hello target){
        this.target = target;
    }
    
    //在相同方法中调用被代理对象,并且实现功能的增强
    @Override
    public void sayHello() {
        System.out.println("sayHello method start");
        target.sayHello();
        System.out.println("sayHello method end");
    }
}

测试

public static void main(String[] args) {
    Hello hello = new HelloImpl();
    hello.sayHello();
    
	System.out.println("=================below is proxy mode====================");

    Hello helloProxy = new HelloImplProxy(hello);
    helloProxy.sayHello();
}

结果

hello, world
=================below is proxy mode====================
sayHello method start
hello, world
sayHello method end

从上面的结果可以看出,被代理对象实现了基础的业务逻辑,代理对象保留了原本业务逻辑的调用,并且实现了对被代理对象的功能的增强。

JAVA设计代理模式应用场景,java设计的代理模式设计案例

四、动态代理

静态代理模式可以解决对业务逻辑进行增强需求的满足,但是会有一个问题,就是如果还有别的功能需要扩展,则需要新增新的代理类,随着需求越来越多,代理类也会越来越多。而动态代理技术则是通过动态生成java字节码的方式,将生成的字节码加载进ClassLoad,生成对应的Class对象,在通过Class对象生成普通java对象的。从而解决代理类数量爆炸的问题。下面我们就从代码层面讲解java的两种动态代理技术:

1、jdk动态代理代码

public static void main(String[] args) {
Hello hello = new HelloImpl();
//        Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[]{Hello.class}, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                System.out.println("proxy method begin");
//                Object ret = method.invoke(hello, args);
//                System.out.println("proxy method end");
//                return ret ;
//            }
//        });

Hello helloProxy = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[]{Hello.class},
        (proxy, method, as) -> {
         System.out.println("proxy method begin");
        Object ret = method.invoke(hello, as);
        System.out.println("proxy method end");
        return ret ;
        });
hello.sayHello();
System.out.println("=================below is dynamic proxy mode====================");
helloProxy.sayHello();

结果

hello, world
=================below is dynamic proxy mode====================
proxy method begin
hello, world
proxy method end

可以看出,jdk的动态代理有一个关键点,就是接口,只有被代理对象实现了接口的时候,jdk动态代理才可以通过实现相同接口的方式来进行代理对象的生成,从而实现功能的扩展。那么,如果需要被代理的对象

2、cglib代理

public static void main(String[] args) {
HelloImpl hello = new HelloImpl();

hello.sayHello();

System.out.println("=================below is cglib proxy mode====================");

Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(hello.getClass().getClassLoader());
enhancer.setSuperclass(HelloImpl.class);
enhancer.setCallback(new MethodInterceptor() {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("proxy method begin");
        Object ret = method.invoke(hello, objects);
        System.out.println("proxy method end");
        return ret;
    }
});

HelloImpl helloCglibProxy = (HelloImpl) enhancer.create();
helloCglibProxy.sayHello();

结果

hello, world
=================below is cglib proxy mode====================
proxy method begin
hello, world
proxy method end

可以看到,cglib代理的实现方式与jdk动态代理是完全不同的,究其原理来说,jdk动态代理是通过实现接口的方式来实现代理对象的生成,而cglib代理,不需要接口,它是通过继承的方式来实现代理对象的生成。

原文链接:https://blog.csdn.net/whhwch1986/article/details/113399055