1. 什么是代理
1.1 例子解释
1. 生活中的例子,常见的商家卖东西,
商家就是代理,工厂是目标,买东西的人是客户端。
买东西不能找厂家买东西,工厂不卖,得找商家,
商家在其中形成了代理。
2. 房东--租房中介--租房人也是上面的关系
3. 程序中代理表示:
a类访问c类中的方法 但是c类不让a类访问
创建一个b代理 c让b访问
1.2 作用
1.功能增强 在原有的功能上 新增了额外的功能 , 新增的功能, 叫功能增强
2.控制访问 代理类不让你访问目标 如商家不让用户访问厂家
3.在项目中使用,使用别人的代码,在不改变原来目标方法功能的前提下,
可以在代理中增强自己的功能代码
2. 静态代理
2.1 优缺点分析
代理类是自己手工实现的,自己创建一个Java类,表示代理类。
你所代理的目标是确定的,好理解
缺点:
目标类增多 代理类可能成倍增加 数量太多...
接口中 增加功能后 会影响代理类多实现功能...
2.2 以厂家卖u盘用代码说明
package com.lovely.static_proxy;
public interface UsbSell {
float sell(int amount);
}
package com.lovely.static_proxy;
public class Factory implements UsbSell {
@Override
public float sell(int amount) {
System.out.println("工厂卖u盘");
return 10.0f;
}
}
package com.lovely.static_proxy;
public class TaoBao implements UsbSell {
private Factory factory = new Factory();
@Override
public float sell(int amount) {
float price = factory.sell(amount) + 15.0f;
System.out.println("淘宝返回优惠券");
return price;
}
}
package com.lovely.static_proxy;
public class WeiSolder implements UsbSell {
private Factory f = new Factory();
@Override
public float sell(int amount) {
return f.sell(amount) + 1.0f;
}
}
package com.lovely.static_proxy;
public class BuyMain {
public static void main(String[] args) {
TaoBao tb = new TaoBao();
float price = tb.sell(10);
System.out.println("经过代理taobao 价格 " + price);
WeiSolder w = new WeiSolder();
price = w.sell(10);
System.out.println("经过代理微商 价格 " + price);
}
}
3. 动态代理
3.1 什么是动态代理
概念
在程序执行过程中,使用jdk的反射机制,
创建代理类对象(无需写代理类了),
并动态的指定要代理目标类(厂家)。
又 : 动态代理是一种创建Java对象的能力,
让你不用创建代理类,就能创建代理类对象。
代理目标是活动的,可设置的
给不同的目标随时创建代理
优点:
解决静态代理的弊端
在静态代理中目标类很多的时候 可使用动态代理
修改接口中的方法 不会影响代理类
3.2 jdk实现原理
要求:
jdk的动态代理 目标类与代理类必须实现相同的接口,才可代理
jdk动态代理实现:
InvocationHandler: 只有一个invoke()方法,里面写代理类实现的功能 1. 调用目标类方法 2. 实现功能增强
public Object invoke(Object proxy, Method method, Object[] args)
InvocationHandler 接口:表示你的代理要干什么。
使用:
1. 创建类实现接口 InvocationHandler
2. 重写invoke方法,把原来静态代理中代理类要完成的功能写在invoke中
Method 类 method.invoke(目标对象,"参数值")
Proxy 类 使用proxy类的方法 表示创建对象 代替new
Proxy.newProxyInstance(more args...); 创建代理对象
public static Object newProxyInstace(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
代理目标类, 创建代理类对象(返回值)
参数
1. ClassLoader loader 类加载器,负责向内存中加载对象。目标对象的类加载器。
a.getClass().getClassLoader()
2. Class<?>[] interfaces 目标对象实现的接口
3. InvocationHandler 代理类要完成的功能
3.3 代码描述
package com.lovely.dynamite_proxy;
public interface UsbSell {
public abstract float sell(int amount);
}
package com.lovely.dynamite_proxy;
public class UsbKingFactory implements UsbSell {
@Override
public float sell(int amount) {
System.out.println("工厂实现卖u盘,每个" + 10.0f);
return 10.0f;
}
}
package com.lovely.dynamite_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target = null;
public MyInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object returnValue = method.invoke(target, args);
if (target != null) {
float price = (float) returnValue;
price += 20.0f;
returnValue = price;
}
System.out.println("这里调用目标方法,还可做其它操作,如写一些其它功能");
return returnValue;
}
}
package com.lovely.dynamite_proxy;
import java.lang.reflect.Proxy;
public class BuyMain {
public static void main(String[] args) {
UsbSell usbKing = new UsbKingFactory();
MyInvocationHandler handler = new MyInvocationHandler(usbKing);
UsbSell proxy = (UsbSell)Proxy.newProxyInstance(UsbKingFactory.class.getClassLoader(),
UsbKingFactory.class.getInterfaces(), handler);
float price = proxy.sell(1);
System.out.println("价格为 " + price);
}
}
工厂实现卖u盘,每个10.0
这里调用目标方法,还可做其它操作,如写一些其它功能
价格为 30.0
cglib(code generating libray)动态代理: 第三方的工具库 创建代理对象
原理是继承: cglib通过继承目标类 创建子类 重写方法 对功能修改
对于无接口的类 使用cglib实现
cglib在spring mybatis中使用较多