- 靜態代理
- 動態代理 - jdk代理
- 動態代理 - cglib代理
定義Person接口對象
public interface Person {
public void invoke();
}
定義Student對象實現Person
@Slf4j
public class Student implements Person{
@Override
public void invoke() {
log.info("學生處理事情...");
}
}
1.靜態代理的實現
- 靜態代理類要實現被代理對象接口
- 被代理對象接口作爲靜態代理類的屬性
- 被代理對象作爲靜態代理類的構造函數入參傳入
- new PersonProxy()
@Slf4j
public class PersonProxy implements Person{
private Person person;
public PersonProxy(Person person){
this.person = person;
}
@Override
public void invoke() {
log.info("代理類統一開始處理");
person.invoke();
log.info("代理類統一結束處理");
}
public static void main(String[] args) {
Student s = new Student();
PersonProxy personProxy = new PersonProxy(s);
personProxy.invoke();
}
}
2.1動態代理實現之jdk動態代理
- 代理類需要實現InvocationHandler接口
- 重寫invoke 方法.通過反射機制調用方法method.invoke(object,args) object-被代理的對象 args-參數
- 代理類必須有個屬性對象Object-通過代理類的構造函數傳參進行設值
- Proxy.newProxyInstance(loader,clazz,testInvocationHandler)
loader -類加載器
clazz - 獲取代理類實現的所有接口
testInvocationHandler- 委託的代理類
@Slf4j
public class TestInvocationHandler implements InvocationHandler{
private Object object;
public TestInvocationHandler(Object o){
this.object = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("類名-{},方法名-{},參數-{}",proxy.getClass().getName(),method.getName(), JSONArray.toJSONString(args));
// 調用方法、反射機制調用
Object o = method.invoke(object,args);
return o;
}
public static void main(String[] args) {
// 創建代理類
Student s = new Student();
// 獲取類加載器
ClassLoader loader = Thread.currentThread().getContextClassLoader();
// 獲取被代理類實現的所有接口
Class<?>[] clazz = s.getClass().getInterfaces();
// 創建需要委託的代理類
TestInvocationHandler testInvocationHandler = new TestInvocationHandler(s);
// 生成代理類
Person proxy = (Person) Proxy.newProxyInstance(loader,clazz,testInvocationHandler);
// 通過代理類調用
proxy.invoke();
}
}
2.2動態代理實現之cglib代理
定義對象MyAspect
public class MyAspect {
public void before(){
System.out.println("切面-before");
}
public void around(){
System.out.println("切面-around");
}
public void after(){
System.out.println("切面-after");
}
}
- new enhancer 對象
- enhancer.setSuperclass(student.getClass())
- 設置回調函數 new MethodInterceptor 方法攔截器
- 創建代理類 enhancer.create()
public class TestCglibFactory {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Volumes/zhengStanC");
// 目標類
final Student student = new Student();
// 切面類
final MyAspect myAspect = new MyAspect();
// 代理類 採用cglib
// 1.1 核心類,new enhancer 對象
Enhancer enhancer = new Enhancer();
// 1.2確認父類
enhancer.setSuperclass(student.getClass());
// 1.3 設置回調函數 new MethodInterceptor 方法攔截器
// 參數 目標對象,方法,參數、代理方法
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 切面前
myAspect.before();
// 執行目標方法
Object obj = methodProxy.invokeSuper(proxy,args);
// 切面後
myAspect.after();
return obj;
}
});
// 1.4 創建代理類
Student proxService = (Student) enhancer.create();
proxService.invoke();
}
}
總結
靜態代理
只能代理某個特定的對象,擴展性不好,如果有多個對象都需要創建對應的代理類
動態代理之jdk代理
只能實現代理實現接口的被代理類,如果是被代理類是實現類,是不能夠通過jdk代理實現(Proxy.newProxyInstance 裏的參數class-獲取的是被代理類所有實現接口的類)
那對於代理實現類需要怎麼處理?這時就可以通過cglib代理來實現。
cglib代理
通過繼承的方式來實現的,委託代理會爲每個被代理類創建一個新的類,並且繼承該父類,進而實現代理增強。