1.檔案清單:
業務介面:UserService
業務實現:UserServiceImpl
代理類的調用Handler實現:ProxyHandler
2.少廢話,貼代碼:
package com.niewj.service;import com.niewj.model.User;public interface UserService {void add(User user);void delete(User user);}
package com.niewj.service;import com.niewj.model.User;public class UserServiceImpl implements UserService {@Overridepublic void add(User user) {System.out.println("User Saved. & ");}@Overridepublic void delete(User user) {System.out.println("User Deleted. &");}}
package com.niewj.service;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * JDK動態代理類比 * * 1.首先明確什麼是目標對象target,什麼是代理對象proxy!! * * 2.每個代理對象對象都會有一個相關的InvocationHandler對象。 * 當代理對象產生的時候,是建立的代理對象, * 拿著相關的這個InvocationHandler對象,去自動調Handler類中實現的invoke方法的。 * 下面一段話來自@javadoc@ * <p>Each proxy instance has an associated invocation handler. * When a method is invoked on a proxy instance, the method * invocation is encoded and dispatched to the <code>invoke</code> * method of its invocation handler. * * 3.還有就是我發現,我的Eclipse控制台TMD輸出的順序有誤,害的老以為我人品出了什麼問題, * 不知道控制台的資訊是不是不是棧式輸出的。(好繞口) * */public class ProxyHandler implements InvocationHandler {// 就是要給這個目標類建立代理對象。private Object target;// 傳遞代理目標的執行個體,因為代理處理器需要。也可以用set等方法。public ProxyHandler(Object target) {this.target = target;}/* * 這個方法是給代理對象調用的。 * 留心的是內部的method調用的對象是目標對象,可別寫錯。 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object ret = null;// 1.調用前cutIntoBefore(method.getName());ret = method.invoke(target, args);// 2.調用後cutIntoAfter(method.getName());return ret;}public void cutIntoBefore(String mName) {System.err.println("調用____" + mName + "()____方法之前");}public void cutIntoAfter(String mName) {System.err.println("調用____" + mName + "()____方法完後");}}
測試處:
package com.niewj;import java.lang.reflect.Proxy;import org.junit.Test;import com.niewj.model.User;import com.niewj.service.ProxyHandler;import com.niewj.service.UserService;import com.niewj.service.UserServiceImpl;public class SpringProxyTest {@Test@SuppressWarnings("rawtypes")public void testJDKDynamicProxy() {/* 1.擷取UserServiceImpl對象--目標對象--也就是需要被代理的對象。 */UserService userService = new UserServiceImpl();// 擷取當前類名Class clazz = userService.getClass();/* * 2.獲得代理對象。 * 每一個代理對象都有一個相關的InvocationHandler對象,通過這個handler對象的invoke來實現調用中要完成的自訂陷阱行為 * 。 可以使用Proxy類和自訂的調用處理邏輯來產生一個代理對象的。 */UserService userServiceProxy = (UserService) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(),new ProxyHandler(userService));userServiceProxy.add(new User("dotjar"));userServiceProxy.delete(new User("DDD"));}}
3.總結:總結在代碼裡,look up