1.代理
中介,黄牛,商家平台
eg:某多多,商家跟工厂批量进货,卖给你;
代理特点:
1.中介和代理他们要做的事情是一致的:东西卖出去。
2.某多多是工厂代理,客户是目标。
3.中介是代理,不能白干活,需要收取费用(加价)
4.代理不让你访问到目标。
2.代理模式
**代理模式:**代理模式是指,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。
简单说:使用代理对象,是为了在不修改目标对象的基础上,增强主业务逻辑。
客户类真正的想要访问的对象是目标对象,但客户类真正可以访问的对象是代理对象。
客户类对目标对象的访问是通过访问代理对象来实现的,当然,代理类与目标类要实现同一个接口。
2.1使用代理模式的作用:
1.功能增强 :在你原有的功能上,增强了额外的功能。新增加的功能,叫做功能增强。
2.控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。
静态代理
静态代理较为简单,直接上代码
客户:
public class Client {
public static void main(String[] args) {
PDD pdd = new PDD();
int price = pdd.sell(1);
System.out.println("买一个u盘的单价" +price+"元");
}
}
工厂:
public class factory implements SellService {
//100元一个,以nums个一起进货
@Override
public int sell(int nums) {
System.out.println(" 目标类中的方法调用,Factory中的sell");
return nums*100;
}
}
某平台(代理)
public class PDD implements SellService{
//声明 商家代理的厂家具体是谁
private factory f=new factory();
int nums=100;
@Override
public int sell(int nums) {
//向厂家发送订单,告诉厂家,我买了U盘,厂家发货
int price;//厂家的价格
price = f.sell(nums);
//加价卖出
price=price+10;
return price;
}
}
接口
public interface SellService {
public int sell(int nums);
}
动态代理
jdk动态代理:使用java反射包中的类和对象实现动态代理的功能。
反射包java.lang.reflect ,里面有三个类:Proxy,Method和InovcationHandler.
InovcationHandler.接口:
就一个方法invoke()
invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能就写在invoke()方法中。
代理类完成的功能:
1)调用目标方法,执行目标方法的功能。
2)功能增强,在目标方法调用时,增强功能。
方法原型:public Object invoke(Object proxy, Method method, Object[] args)
参数:
Object proxy:jdk创建的代理对象,无需赋值。
Method method:目标类中的方法,jdk提供method对象的
Object[] args:目标类中方法的参数
怎么用:
1.创建类实现接口InovcationHandler
2.重写invoke()方法,把原来静态代理中代理类要完成的功能,卸载这里。
Method类:
表示方法的,确切的说就是目标类中的方法。
作用:通过Method可以执行某个目标类的方法,Method.invoke();
method.invoke(目标对象,方法的参数)
Object ret =method.invoke(service2,“李四”);
说明:method.invoke()就是用来执行目标方法的,等同于静态代理中的
//向厂家发送订单,告诉产假,我买了U盘,厂家发货
float price = factory.sell(amount);//厂家的价格
Proxy类:
核心的对象,创建代理对象。之前创建对象都是new类的构造方法()
现在我们是使用proxy类的方法,代替new的使用。
方法:静态方法newProxyInstance()
作用是:创建代理对象,等同于静态代理中的TaoBao taoBao = new TaoBao();
参数:
1.ClassLoader loader 类加载器,负责向内存中加载对象的。使用反射获取对象的ClassLoader类a,a.getClass().getClassLoader(),目标对象的类加载器
2.Class<?>[] interfaces:接口,目标对象实现的解耦,也是反射获取的。
3.InvocationHandler h:我们自己写的,代理类要完成的功能
返回值:就是代理对象。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
3.实现动态代理的步骤:
1)创建接口,定义目标类要完成的功能
2)创建目标类实现接口
3)创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能(调用目标方法,增强功能)
4)使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。
例子:
动态代理接口类
public interface SellService {
public void sell();
}
目标类
ublic class Factory implements SellService {
//100元一个,以nums个一起进货
@Override
public void sell() {
System.out.println(" 目标类中的方法调用,Factory中的sell");
}
}
动态代理类
// 动态代理类
public class ProxyInvocationHandler implements InvocationHandler {
//动态代理类拿到 抽象角色:出售
private SellService sellService;
public void setSellService(SellService sellService) {
this.sellService = sellService;
}
//生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
sellService.getClass().getInterfaces(),this);
}
// proxy : 代理类 method : 代理类的调用处理程序的方法对象.
// 处理代理实例上的方法调用并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//核心:本质利用反射实现!
Object result = method.invoke(sellService, args);
return result;
}
}
Client
public class Client {
public static void main(String[] args) {
Factory factory = new Factory();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setSellService(factory);
SellService proxy = (SellService) pih.getProxy();
proxy.sell();
}
}