1. 什么是代理模式
法官(调用者)→律师(代理对象)→被代理人(真实对象)
客户(调用)→外包公司(代理)→开发工程师(真实)
法官经过律师访问被代理人,那么调用者调用对象之前产生一个代理对象,而代理对象需要和真实对象建立代理关系(律师委托合同),所以代理分为以下两个步骤:
1.代理对象和真实对象建立代理关系(合同关系)
2.实现代理对象的代理逻辑方法(律师组织辩论/公司组织开发)
代理对象的作用:在真实对象被访问之前或者之后,加入对应的逻辑(大小事务包干,鞍前马后)
1.1 jdk动态代理
JDK自带的功能,必须使用接口,属于java.lang.reflect.*包下
- 依赖于接口实现,必须借助一个接口才能产生代理对象
- 建立代理关系,生成代理对象Proxy.newProxyInstance()
- 实现代理逻辑方法invoke()
流程:
1.定义接口和实现类
2.代理逻辑类实现java.lang.reflect.InvocationHandler接口
//定义接口
public interface HelloWorld {
public void sayHelloWorld();
}
//提供实现类
public class HelloWorldImpl implements HelloWorld {
@override
public void sayHelloWorld() {
sout("Hello World");
}
//开始动态代理
//JDK中代理逻辑类需要实现InvocationHandler接口
public class JdkProxyExample implements InvocationHandler {
//真实对象
private Object target = null;
/**
*step1:
*建立代理对象和真实对象的代理关系,并返回代理对象
*@return 代理对象
*/
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
/**
*step2:
*代理逻辑方法
*@param proxy 代理对象, method 当前调度方法, args 当前方法参数,
*@return 代理结果返回
*/
@override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
sout("进入代理逻辑方法");
sout("调用真实对象之前的服务");
Object obj = method.invoke(target, args);//相当于调用sayHelloWorld()
sout("调用真实对象之后的服务");
return obj;
}
}
测试JDK动态代理
public void testJdkProxy() {
JdkProxyExample jdk = new JdkProxyExample();
//因为挂在HelloWorld下,所以声明代理对象HelloWorld proxy
HelloWorld proxy = (HelloWorld)jdk.bind(new HelloWorldImpl());
//proxy已经是一个代理对象,会进入代理逻辑方法
proxy.sayHelloWorld();
}
1.2 cglib动态代理
不能提供接口的环境,则采用第三方技术,要求一个非抽象类(的被代理人)
- 实现MethodInterceptor接口
- 建立代理关系,生成代理对象Enhancer
- 实现代理逻辑方法inercept()
public class ReflectServiceImpl {
public void sayHello(String name){
System.err.println("Hello " + name);
}
}
//开始动态代理
public class CglibProxyExample implements MethodInterceptor {
/**
*step1: 建立代理关系
*生成CGLIB代理对象
*@param cls:非抽象类 真实对象
*@return 类的CGLIB代理对象
*/
public Object getProxy(Class cls){
//CGLIB enhancer增强类对象
Enhancer enhancer = new Enhancer();
//设置增强类型
enhancer.setSuperclass(cls);
//定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
enhancer.setCallback(this);//该方法设置哪个类为代理类,则这个类就需要实现MethodIntercetor的intercept方法
return enhancer.create();
}
/**
*step2:代理逻辑方法
*@param proxy 代理对象, args 方法参数, methodproxy方法代理
*@return 代理逻辑返回
*/
@override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
sout("调用真实对象之前的服务");
Object result = methodProxy.invoke(proxy, args);
sout("调用真实对象之后的服务");
return result;
}
}
测试CGLIB动态代理
public void testCGLIBProxy() {
CglibProxyExample cpe = new CglibProxyExample();
ReflectServiceImpl obj = (ReflectServiceImpl ) cpe.getProxy(ReflectServiceImpl.class);
obj.sayHello("hello, world");
}