目录
前言:
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方法可以创建多个,不同的公共逻辑,哈哈,就看到时候的具体使用场景了