~~结构型-代理模式
一:动态代理
1:概念
动态代理模式则是通过创建代理类(proxy)的方式来访问服务,代理类通常会持有一个委托类对象,代理类不会自己实现真正服务,而是通过调用委托类对象的相关方法,来提供服务,所以其实我们调用的还是委托类的服务,但是中间隔了一个代理类。这么做是有好处的,我们可以在访问服务之前或者之后加一下我们需要的操作。例如Spring的面向切面编程,我们可以在切入点之前执行一些操作,切入点之后执行一些操作。这个切入点就是一个个方法。这些方法所在类肯定就是被代理了,在代理过程中切入了一些其他操作。
简单理解:我是个接口,我能直接获取实现类,但是我不获取,我非要通过其对象(代理对象,实现Proxy接口)来获取。通过代理对象获取我的实现类,然后再调用方法。
代理对象可以再返回的对象中对指定的方法进行增强。比如在帮我调用之前做一些动作,调用之后在做一些动作。
因为整个代理过程不是具体的某个接口类,可以传入不同的接口类,因此被称为动态代理。
反之,只是代理某一个具体的接口类,不能动态改变的被称为静态代理。
2:被代理的类是接口
三个角色
a:被代理的类:一般是接口类
b:被代理的接口的实现类 //不关注
c:代理类
1:使用java.lang.reflect.Proxy.newProxyInstance方法
2:newProxyInstance方法有三个参数:
a:类加载器
b:要增强类所在的方法所在接口类,支持多个接口
c:实现InvocationHandler接口的类,创建要代理的对象,编写增强业务逻辑代码。
3:底层代码实现
图1
图2
图3
上图2,图3是同一张图
图1newProxyInstance方法只是获取到了代理对象,代理对象的方法并未执行,只有在调用对应的方法才会执行代理对象的增强逻辑(如图1中的dao.add)。
3:被代理的类没接口
三个角色
a:被代理的类,一个普通的类,如下图中User类
b:被代理的类的子类 //不关注
c:代理类
代用CGLIB技术,通过代理创建当前类的子类实现,如图:
二:静态代理
1:概述
静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类。
简单理解:我获取到了我的实现类A的对象a,但是我不想通过a直接调用相关接口,我让a作为参数传入另一个实现类构造器B(静态代理类),在B中我就有了a对象,然后在实现方法中使用a调用相关参数,并可以做一些其它动作(增强动作)
多线程底层使用的就是静态代理模式。
2:代码实现
package com.test.daili;
/**
* 静态代理
*/
public class StaticDaiLiTest {
public static void main(String[] args) {
Person renter = new Renter();
RenterProxy proxy = new RenterProxy(renter);//根据代理类获取被代理的真实实现类
proxy.rentHouse();
}
}
/**
* 接口类
*/
interface Person {
//租房
public void rentHouse();
}
//被代理接口类的实现类
class Renter implements Person{
@Override
public void rentHouse() {
System.out.println("租客租房成功!");
}
}
//静态代理类
class RenterProxy implements Person{
private Person renter;
public RenterProxy(Person renter){
this.renter = renter;
}
@Override
public void rentHouse() {
System.out.println("中介找房东租房,转租给租客!");
renter.rentHouse();
System.out.println("中介给租客钥匙,租客入住!");
}
}