代理模式
- 静态代理
需要为每个代理者(类、接口)都创建一个代理类,让代理类继承或实现被代理者,重写被代理
者中的方法,重写之后就可以增加业务逻辑,还需要调用被代理者中的方法 - 动态代理
1、JDK自带实现多态代理的方法(Proxy)
1.1要求被代理类(目标类)需要实现一个接口
1.2、步骤
1.2.1、创建被代理者类的对象(目标对象)
1.2.2、获取目标类的类加载器:ClassLoader对象
1.2.3、获取目标类所实现的所有接口
1.2.4、需要创建InvocationHandler对象
2、CGLib
静态代理
/*
我们将创建一个 Image 接口和实现了 Image 接口的实体类。ProxyImage 是一个代理类,减少 RealImage 对象加载的内存占用。
ProxyPatternDemo,我们的演示类使用 ProxyImage 来获取要加载的 Image 对象,并按照需求进行显示。
简单来说,代理类就是比原来的类的功能更加的强大,功能更全
*/
public class StaticProxyDemo {
public static void main(String[] args) {
Image image = new ProxyImage("lhm.jpg");
//需要从内存中加载
image.disPlay();
System.out.println("---------------");
//不需要从内存中加载
image.disPlay();
}
}
interface Image{
void disPlay();
}
class RealImage implements Image{
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
private void loadFromDisk(String fileName){
System.out.println("正在从磁盘加载图片....");
}
@Override
public void disPlay() {
System.out.println("展示的图片是:" + fileName);
}
}
class ProxyImage implements Image{
private RealImage ri;
private String fileName;
public ProxyImage(String fileName){
this.fileName = fileName;
}
@Override
public void disPlay() {
if (ri == null){
ri = new RealImage(fileName);
}
ri.disPlay();
}
}
动态代理
/*
1、动态代理
ava.lang.reflect.Proxy:生成动态代理类和对象;
java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现对真实角色的代理访问。
每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象。
2、步骤
1、创建被代理者类的对象(目标对象)
2、获取目标类的类加载器:ClassLoader对象
3、获取目标类所实现的所有接口
4、需要创建InvocationHandler对象
*/
public class DynamicProxyDemo {
public static void main(String[] args) {
RealSubject rs= new RealSubject();
//MyInvocationHandler mih = new MyInvocationHandler(rs);
/*Subject proxySubject = (Subject) Proxy.newProxyInstance(*//*ClassLoader.getSystemClassLoader(),*//* Subject.class.getClassLoader(),
RealSubject.class.getInterfaces(),
mih);*/
Subject proxySubject = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
RealSubject.class.getInterfaces(),
(proxy, method, args1) -> {
if (method.getName().equalsIgnoreCase("says")){
System.out.println("说话方法");
return method.invoke(rs, args1);
}else if (method.getName().equalsIgnoreCase("sellbooks")){
System.out.println("卖书方法");
return method.invoke(rs, args1);
}
return null;
});
proxySubject.sellBooks();
System.out.println("==============================");
proxySubject.Says();
System.out.println("------------------------------");
System.out.println(proxySubject);//对象输出值为null
boolean present = Optional.of(proxySubject).isPresent();
System.out.println(present);//true有值非空
System.out.println(proxySubject instanceof Subject);//true
}
}
interface Subject{
void sellBooks();
void Says();
}
class RealSubject implements Subject{
@Override
public void sellBooks() {
System.out.println("卖书");
}
@Override
public void Says() {
System.out.println("和客人说话");
}
}
class MyInvocationHandler implements InvocationHandler{
private Subject sb;
public MyInvocationHandler(Subject sb){
this.sb = sb;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
proxy:代理类
method:正在调用的方法
args:方法的参数
*/
System.out.println("调用代理类...");
if (method.getName().equalsIgnoreCase("sellBooks")){
method.invoke(sb,args);
System.out.println("调用的卖书的方法");
}else if (method.getName().equalsIgnoreCase("Says")){
method.invoke(sb,args);
System.out.println("调用的是说话的方法");
}
return null;
}
}