JAVA代理模式-JDK动态代理的实现(二)
传送门:JAVA代理模式-静态代理的实现(一)
JAVA代理模式-JDK动态代理的实现(二)
JAVA代理模式-cglib动态代理的实现(三)
JAVA代理模式-三种代理模式的对比(四)
代理模式的简介可查看此链接。
JAVA代理模式-静态代理的实现(一)
JDK动态代理的实现:
Java中提供了一个动态代理类Proxy,提供了一个创建代理对象的静态方法
(newProxyInstance方法)来获取代理对象。
考虑以下场景,你需要去中介手里买电影票,中介会在售票的基础上增强手续费。
则电影院为真实主题类,而中介则为代理类,在真实主题类售卖电影票的基础上,增强功能收取了一定的手续费。
1. 编写电影院售票的接口。
interface Cinema{
void sell();
}
2. 编写真实主题类,宁波电影院实现电影院接口,实现真正的售票动作。
class NbCinema implements Cinema{
@Override
public void sell() {
System.out.println("出售电影票");
}
}
3. 编写代理工厂类,通过Java中提供的一个动态代理类Proxy,动态生成代理类。
class CinemaProxyFactory {
public Cinema getProxyObject(NbCinema nc){
/*
该方法使用Proxy获取代理对象
*/
/*
newProxyInstance()方法参数说明:
ClassLoader loader: 类加载器,用于加载代理类,使用真实对象的类加载器即可
Class<?>[] interfaces: 真实对象所实现的接口,代理模式真实对象和代理对象实现相同的接口
InvocationHandler h: 代理对象的调用处理程序
*/
Cinema obj = (Cinema) Proxy.newProxyInstance(
nc.getClass().getClassLoader(),
nc.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("收取500中介费");
Object invoke = method.invoke(nc, args);
return invoke;
}
}
);
return obj;
}
}
4. 客户调用代理类,从中介手中买票。
public class JDKProxyClient {
public static void main(String[] args) {
CinemaProxyFactory pf = new CinemaProxyFactory();
Cinema ca = pf.getProxyObject(new NbCinema());
ca.sell();
}
}
实验结果:
动态代理使用时的细节:
因为其中使用了反射机制,如果想要更深入了解,可以参考:
JAVA通过反射使用公共构造方法和私有构造方法来创建对象(一)
JAVA通过反射获取公共和私有成员变量和成员方法(二)
JDK动态代理完整代码:
package com.csdn.proxy.JDKproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Cinema{
void sell();
}
class NbCinema implements Cinema{
@Override
public void sell() {
System.out.println("出售电影票");
}
}
class CinemaProxyFactory {
public Cinema getProxyObject(NbCinema nc){
/*
该方法使用Proxy获取代理对象
*/
/*
newProxyInstance()方法参数说明:
ClassLoader loader: 类加载器,用于加载代理类,使用真实对象的类加载器即可
Class<?>[] interfaces: 真实对象所实现的接口,代理模式真实对象和代理对象实现相同的接口
InvocationHandler h: 代理对象的调用处理程序
*/
Cinema obj = (Cinema) Proxy.newProxyInstance(
nc.getClass().getClassLoader(),
nc.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("收取500中介费");
Object invoke = method.invoke(nc, args);
return invoke;
}
}
);
return obj;
}
}
public class JDKProxyClient {
public static void main(String[] args) {
CinemaProxyFactory pf = new CinemaProxyFactory();
Cinema ca = pf.getProxyObject(new NbCinema());
ca.sell();
}
}