动态代理两种实现方法

目录

前言:

一:基于创建proxy对象使用代理

1.1真实对象

2.代理对象

3.代理测试

 二:基于继承InvocationHandler使用代理

1.1真实对象

2.代理对象

3.代理测试


前言:

Java代理和生活中的代理概念类似,

例如:生活中一个类似的卖保险:存在着有的保险公司,雇佣非本公司人员卖产品:

那些人员充当本公司代理,帮助本公司售卖保险产品;

然而:Java中呢:这个代理的概念是指:

代理内部创建对象,使用反射

小的说:对象这个class,,也不需要必须要获取到存在着的对象,可以使用代理对象统一处理;

在大点:各业务模块接口层,在实际调用业务api时,进行横向扩展:还是生成一个代理对象,执行完“横向扩展代码后”、在执行原方法;

是不是感觉和sping的aop类似,spring 的aop也用到了代理(两种代理方式自动切换)

一:基于创建proxy对象使用代理

1.1真实对象

public intetface MainService{

    String bug (BigDecimal money);

    void show;
}

public class MainServiceImpl implements MainService{

    @Override
    public Strig bug(BigDecimal money){
        return "真实对象,我不想花"+money+"钱去买游戏币!"
    }

    @Override
    public void show(){
        return "真实对象,其实我没钱买币了!"
    }
}

2.代理对象

本层抽取针对上述两个api一起抽取第一种业务使用场景,也可以一个api抽取一个使用场景()

public interface ProxyService{

 MainService getProxyObject();

 void business();

}

public class ProxyServiceImpl implements ProxyService{

    @Override
    public MainService getProxyObject(){
        System.out.println("获取代理对象实现方式1");
        //组织代理对象
        MainServiceImpl mainService = new MainServiceImpl(); 
        /**
         * Proxy 提供用户创建动态代理类和实例的静态方法
         *  1. newProxyInstance() 通过此方法创建代理实例
         *    参数1: 定义代理类的类加载器(真实对象)
         *      参数2 :真实对象实现的接口数据
         *        参数3 : 调用处理程序,执行方法
         *  通过内部逻辑,也就是增强参数、增强方法体、增强返回值,进行横向扩展业务公共逻辑等
         *
         */

        MainService proxy_main =             
(MainService)Proxy.newProxyInstance(mainService.getClass.getClassLoader(),mainService.getClass().getInterfaces(),new InvocationHandler(){
            /**
			 * invoke 核心代码、代理对象调用的所以方法都会触发
			 *  
			 *    参数1: 代理对象本身
			 *      参数2 :代理对象调用的方法,
			 *        参数3 : 代理对象调用方法时:传递的实际参数
			 *
			 */
            @Override
			public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
				
				//选择具体的业务api进行加强
				if(method.getName().equals("buy")){
					System.out.println("代理对象:加强buy");
					//1.增强参数
					BigDecimal money  = (BigDecimal) args[0];
					money = money.multiply(new BigDecimal("1000"));
					//2.增强方法体,增加真实对象业务api以外的公共业务处理
					System.out.println("代理对象增强方法体buy:增加业务处理");
					//使用增强后的参数进行业务处理
					String result = (String)method.invoke(mainService,money);
					result result+"代理对象增强返回值";
				}else{
					System.out.println("代理对象:加强show");
					
					//如果没有,原样输出
					Object obj = method.invoke(mainService,args);
					result obj;
				}
			
			}

		});

        return "真实对象,我不想花"+money+"钱去买游戏币!"
    }

    @Override
    public void business(){
        System.out.println("代理对象业务处理api");
		MainService proxyMain = this.getProxyObject();
		System.out.println("代理对象,大特价,可以进货了");
		String result = proxyMain.buy(new BigDecimal("100"));
		System.out.println("代理对象代理结果:"+result);
		proxyMain.show();
    }
}

3.代理测试

public class Test{

    public static void main(String[] atgs){
        //代理实现方式1 进行业务处理
        ProxyServiceImpl proxyService = new ProxyServiceImpl();
        proxyService.business();
        System.out.println("使用的对象是:"+proxyService.getClass());

    }
}

 二:基于继承InvocationHandler使用代理

1.1真实对象

public intetface MainService{

    String bug (BigDecimal money);

    void show;
}

public class MainServiceImpl implements MainService{

    @Override
    public Strig bug(BigDecimal money){
        return "真实对象,我不想花"+money+"钱去买游戏币!"
    }

    @Override
    public void show(){
        return "真实对象,其实我没钱买币了!"
    }
}

2.代理对象

本层抽取针对上述两个api一起抽取第一种业务使用场景,也可以一个api抽取一个使用场景()

public class Proxy2ServiceImpl implements InvocationHandler(){

	private final MainServiceImpl mainService;
	public Proxy2ServiceImpl(MainService mainService){
		this.mainService = mainService;
	}

	@Override
	public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
		System.out.println("获取代理对象实现方式2");
		Object invoke = method.invoke(mainService,args);
		return invoke;
	}

}

3.代理测试


public class Test2{

    public static void main(String[] atgs){
        //代理实现方式2 进行业务处理
		MainServiceImpl mainService = new MainService();
        Proxy2ServiceImpl proxy2Service = new Proxy2ServiceImpl(mainService);
        MainService proxyMain = (MainService)Proxy.newProxyInstance(
									mainService.getClass().getClassLoader,
									new Class[]{MainService.Class},
									proxy2Service);
		//每调用一个真实对象的api,都会调用
		String a = proxyMain.buy(new BigDecimal("100"));
		System.out.println(a);
		proxyMain.show();
        System.out.println("使用的对象是:"+proxyService.getClass());

    }
}

下面的实现方式,简单快速一点,但是方式1,business方法可以创建多个,不同的公共逻辑,哈哈,就看到时候的具体使用场景了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值