使用一个简单场景来描述代理模式:
1. 顾客买阿迪达斯鞋,不找原厂商买,找二道贩子买,二道贩子就是一个代理
2. 代理不会改变最终顾客到手的东西--鞋
3. 二道贩子也不会按照鞋的拿货价卖给你,他屏蔽了鞋的原始价钱信息,按照自己定的价卖给你
直接上代码,代码中实现了三种代理方式:①静态 ②jdk动态 ③cglib
其中 cglib 的方式需要引入pom依赖如下:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
代码如下, 都写在一个类里方便观看:
package com.haopan.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
System.out.println("静态代理:");
System.out.println("静态代理: 客户端向代理买鞋, 花费: " + AdidasFactoryProxy.getInstance().getStaticProxyCost() + "$");
System.out.println();
System.out.println("动态代理:");
System.out.println("JDK动态代理: 客户端向代理买鞋, 花费: " + AdidasFactoryProxy.getInstance().getJdkProxyCost() + "$");
System.out.println();
System.out.println("CgLib代理:");
System.out.println("CGLib代理: 客户端向代理买鞋, 花费: " + AdidasFactoryProxy.getInstance().getCgLibProxyCost() + "$");
}
}
/**
* 阿迪达斯工厂接口
*/
interface IAdidasFactory {
/**
* 获取一双鞋子的价钱
*/
int cost();
}
/**
* 阿迪达斯工厂实现
*/
class AdidasFactory implements IAdidasFactory {
@Override
public int cost() {
System.out.println("我是厂商, 这双鞋子1000$.");
return 1000;
}
}
/**
* 阿迪达斯工厂的代理商
*/
class AdidasFactoryProxy {
// 本段代码使用了<饿汉式单例模式> start
private static final AdidasFactoryProxy INSTANCE = new AdidasFactoryProxy();
private AdidasFactoryProxy() {
}
public static AdidasFactoryProxy getInstance() {
return AdidasFactoryProxy.INSTANCE;
}
// 本段代码使用了<饿汉式单例模式> end
/**
* 静态代理: 编译时代码已经生成
* @return
*/
public int getStaticProxyCost() {
final IAdidasFactory target = new AdidasFactory();
System.out.println("静态代理介入------前");
int returnValue = target.cost();
System.out.println("静态代理介入------后, 我要加价100$块钱卖出去.");
return returnValue + 100;
}
/**
* 动态代理: 运行时通过接口反射出类实例调用方法
* @return
*/
public int getJdkProxyCost() {
final IAdidasFactory target = new AdidasFactory();
IAdidasFactory target2 = (IAdidasFactory) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("动态代理介入------前");
Object returnValue = method.invoke(target, args);
System.out.println("动态代理介入------后, 我要加价100$块钱卖出去.");
return (int) returnValue + 100;
});
return target2.cost();
}
/**
* CGLib代理: 运行时通过创建增强子类来调用方法
* @return
*/
public int getCgLibProxyCost() {
IAdidasFactory target = new AdidasFactory();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object object, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CgLib代理介入------前");
// invokeSuper: 使用回调函数中的object参数,
// Object returnValue = methodProxy.invokeSuper(object, objects);
// invoke: 使用加强对象本身 target
Object returnValue = methodProxy.invoke(target, objects);
System.out.println("CgLib代理介入------后, 我要加价100$块钱卖出去.");
return (int) returnValue + 100;
}
});
IAdidasFactory enhancerProxy = (IAdidasFactory) enhancer.create();
return enhancerProxy.cost();
}
}