转!!java三种代理模式

转自:https://blog.csdn.net/weixin_42255981/article/details/103527327?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-103527327-blog-109050274.pc_relevant_multi_platform_featuressortv2dupreplace&spm=1001.2101.3001.4242.2&utm_relevant_index=4

 

java三种代理模式:不改变源码的情况下,实现对目标对象的功能扩展

 

package com.cmcc.core.domain.vo;
//接口
public interface Isinger {
    void sing();
    void call();
}

 

package com.cmcc.core.domain.vo;
//实现类,目标对象
public class Singer implements Isinger{

    @Override
    public void sing() {
        System.out.println("sing a song");
    }

    @Override
    public void call() {
        System.out.println("call");
    }
}

 

1)静态代理

package com.cmcc.core.domain.vo;

//代理对象-java静态代理
public class StaticProxy implements Isinger{
    private Isinger isinger;

    public StaticProxy(Isinger isinger){
        this.isinger=isinger;
    }


    @Override
    public void sing() {
        System.out.println("问好");
        isinger.sing();
        System.out.println("谢谢");
    }

    @Override
    public void call() {
        System.out.println("call before");
        isinger.call();
        System.out.println("call after");
    }

    public static void main(String[] args) {
        Isinger iSinger = new Singer();
        StaticProxy proxy = new StaticProxy(iSinger);
        proxy.sing();
    }
}

 

 

2)JDK动态代理

利用java自带的反射包

package com.cmcc.core.domain.vo;

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

//代理对象-JDK动态代理
public class JdkDynamicProxy implements InvocationHandler {

    private Isinger target;

    public JdkDynamicProxy(Isinger target) {
        this.target = target;
    }

    public <T> T getInstance(){
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置增强");
        return method.invoke(target);
    }

    public static void main(String[] args) {
//        JdkDynamicProxy dp=new JdkDynamicProxy(new Singer());
//        ((Isinger) dp.getInstance()).sing();

        Singer target = new Singer();
        Isinger proxy = (Isinger) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("向观众问好");
                Object returnValue = method.invoke(target, args);
                System.out.println("谢谢大家");
                return returnValue;
            }
        });
        proxy.sing();

    }
}

 

3)CGLIB动态代理

利用cglib的jar包,可用Spring的核心包中自带的Cglib功能(spring-core-3.2.5.jar)

package com.cmcc.core.domain.vo;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Cglib子类代理工厂
 */
public class CglibProxy implements MethodInterceptor {
    private Isinger target;

    public CglibProxy(Isinger target){
        this.target=target;
    }

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

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//        if (method.getName().equals("call")) {
//            System.out.println("喊叫之前");
//        }else {
//            System.out.println("向观众问好");
//        }
        //执行目标对象的方法
        Object returnValue = method.invoke(target, args);
        System.out.println("谢谢大家");
        return returnValue;
    }


    public static void main(String[] args){
        //目标对象
        Singer target = new Singer();
        //代理对象
        Singer proxy = (Singer)new CglibProxy(target).getProxyInstance();
        //执行代理对象的方法
        proxy.sing();
        proxy.call();
    }


}

 

代理工厂-工具类方式:

package com.cmcc.core.domain.vo;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
//工厂类
public class CglibProxyFactory {
    // 维护目标对象
    public Object target;

    public CglibProxyFactory(Isinger target) {
        this.target = target;
    }

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

 

package com.cmcc.core.domain.vo;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
//代理对象 继承 工厂类
public class SingerProxy extends CglibProxyFactory implements MethodInterceptor {
    public SingerProxy(Isinger target) {
        super(target);
    }


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("向观众问好");
        Object returnValue = method.invoke(target, objects);
        System.out.println("谢谢大家");
        return returnValue;
    }

    public static void main(String[] args) {
        Singer singer = new Singer();
        Singer proxy = (Singer)new SingerProxy(singer).getProxyInstance();
        proxy.sing();
    }

}

 

posted @ 2022-09-26 10:39  乌云de博客  阅读(108)  评论(0编辑  收藏  举报