代理模式是指,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。说直白一点就是在不修改目标对象的基础上,使用代理对象来增强目标对象的业务逻辑方法。
代理模式分为:静态代理和动态代理(jdk动态代理和cglib动态代理)
静态代理就是:代理类在程序运行前就确定好了和目标类的关系,在编译期就实现了。其中静态代理的缺点在于:
1、代码复杂,不便于管理:试想对于代理类,需要和目标类实现相同接口即每个代理类都要实现目标类的的方法,会出现代码重复,且考虑到如果接口增加一个方法,其所有实现类都要重写,维护也麻烦。
2、代理类依赖于目标类:当代理类考虑代理多个服务的时候,不便于实现
动态代理是在程序运行期间根据jvm反射机制动态生成的。
jdk动态代理:基于java反射机制实现的。具体通过使用java.lang.reflect 包提供三个类支持代理模式 Proxy, Method和 InovcationHandler。(要求:求目标对象必须实现接口)
public interface UsbSell {
Object sell(float amount);
}
public class UsbFactory implements UsbSell {
public Object sell(float amount) {
float price = 0;
if (amount > 100){
price = (float) (amount * (1 + 0.2));
}else {
price = (float) (amount * (1 + 0.5));
}
return price;
}
}
public class ProxySeller {
private Object target;
public ProxySeller() {
}
public ProxySeller(Object target) {
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
float res = (Float) method.invoke(target,args);
System.out.println("=="+res);
return proxy;
}
});
}
}
public class Main {
public static void main(String[] args) {
UsbFactory factory = new UsbFactory();
ProxySeller seller = new ProxySeller(factory);
UsbSell proxy = (UsbSell)seller.getProxy();
UsbSell s = (UsbSell)proxy.sell(50);
s.sell(50);
}
}
cglib动态代理:一个开源项目。对于无接口的类,要为其创建动态代理,就要使用 CGLIB 来实现。CGLIB 代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB 生成动态代理,要求目标类必须能够被继承,即不能是 final 的类。
public class Saller {
public float sell(int amount){
float price = 100;
if (amount > 100){
price = (float) (price * (1 + 0.2));
}else {
price = (float) (price * (1 + 0.5));
}
return price;
}
}
public class ProxySaller implements MethodInterceptor {
private Object target;
public ProxySaller() {
}
public ProxySaller(Object target) {
this.target = target;
}
public Object getProxySaller(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
Saller saller = (Saller) enhancer.create();
return saller;
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Float price = (Float) methodProxy.invoke(target,objects);
System.out.println("==="+price);
return price;
}
}
public class Main {
public static void main(String[] args) {
Saller saller = new Saller();
ProxySaller proxySaller = new ProxySaller(saller);
Saller proxy = (Saller) proxySaller.getProxySaller();
proxy.sell(100);
}
}