類A須要完成的工做由類B去完成,類B其實是在類A的基礎上做了一層封裝,類B包括原始類A的業務邏輯以及先後的擴展邏輯,實現了類A的功能擴展
類A→被代理類/代理目標類/委託類
類B→代理類html
手動建立代理類,代理類的實現方法中對對原始的業務邏輯進行了擴展,兩個要點:java
特色:spring
定義一個接口,測試
package com.imooc.spring.aop.service; public interface UserService { public void createUser(); }
委託類,this
package com.imooc.spring.aop.service; public class UserServiceImpl implements UserService{ public void createUser() { System.out.println("執行建立用戶業務邏輯"); } }
代理類,3d
package com.imooc.spring.aop.service; import java.text.SimpleDateFormat; import java.util.Date; //靜態代理是指必須手動建立代理類的代理模式使用方式 public class UserServiceProxy implements UserService{ //持有委託類的對象 private UserService userService ; public UserServiceProxy(UserService userService){ this.userService = userService; } public void createUser() { //添加其餘的邏輯,實現功能擴展 System.out.println("========靜態代理前置擴展功能======"); userService.createUser(); System.out.println("========靜態代理後置擴展功能======"); } }
測試入口類,代理
package com.imooc.spring.aop; import com.imooc.spring.aop.service.UserService; import com.imooc.spring.aop.service.UserServiceImpl; import com.imooc.spring.aop.service.UserServiceProxy; import com.imooc.spring.aop.service.UserServiceProxy1; public class Application { public static void main(String[] args) { UserService userService = new UserServiceProxy(new UserServiceImpl()); userService.createUser(); } }
測試結果,code
========靜態代理前置擴展功能====== 執行建立用戶業務邏輯 ========靜態代理後置擴展功能======
動態代理分爲JDK動態代理、CGLib動態代理orm
接口、委託類沿用上面的Userservice、UserserviceImpl,JDK動態代理須要實現InvocationHandler接口,重寫invoke方法 ,htm
package com.imooc.spring.aop.service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.text.SimpleDateFormat; import java.util.Date; /** * InvocationHandler是JDK提供的反射類,用於在JDK動態代理中對目標方法進行加強 * InvocationHandler實現類與切面類的環繞通知相似 */ public class ProxyInvocationHandler implements InvocationHandler { private Object target;//目標對象,對全部類生效,因此目標對象類型選擇Object public ProxyInvocationHandler(Object target){ this.target = target; } /** * 在invoke()方法對目標方法進行加強 * @param proxy 代理類對象 * @param method 目標方法對象 * @param args 目標方法實參 * @return 目標方法運行後返回值 * @throws Throwable 目標方法拋出的異常 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("========JDK動態代理前置擴展功能======"); Object ret = method.invoke(target, args);//調用目標方法,相似環繞通知中的ProceedingJoinPoint.proceed() System.out.println("========JDK動態代理後置擴展功能======"); return ret; } }
測試入口類,
package com.imooc.spring.aop; import com.imooc.spring.aop.service.*; import java.lang.reflect.Proxy; public class Application { public static void main(String[] args) { UserService userService = new UserServiceImpl(); ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler(userService); //動態建立代理類 //Proxy.newProxyInstance 根據已經存在的接口,實現其相對應的代理類 UserService userServiceProxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler); userServiceProxy.createUser(); } }
測試結果,
========JDK動態代理前置擴展功能====== 執行建立用戶業務邏輯 ========JDK動態代理後置擴展功能======
JDK動態代理邏輯框圖
JDK動態代理主要包括兩個步驟:
1.UserService userServiceProxy =Proxy.newProxyInstance();//建立代理類,newProxyInstance()根據已有的接口,生成對應的代理類
2.userServiceProxy.createUser(); //代理類與委託類實現了相同的接口,代理類實現接口中的業務邏輯
1.Proxy.newProxyInstance()在執行步驟:
動態生成的代理類$Proxy0與委託類UserServiceImpl實現了相同的接口UserService
代理類$Proxy0中包含委託類的對象的引用:targetObject
實現接口中的方法:具體實現代碼來自InvocationHandler實現類中的invoke方法
2.調用userServiceProxy.createUser();實現委託類的功能擴展,createUser()中的代碼對應僞代碼中方法中的業務邏輯
委託類實現了接口,能夠經過JDK動態代理實現功能擴展,委託類沒有接口,則經過CGLib第三方組件實現功能擴展
CGLib第三方組件繼承須要加強的類,產生一個子類,並重寫父類中的方法,實現功能擴展
1.https://www.cnblogs.com/teach/p/10763845.html