動态代理
接口UserManager
1. /***
2. * 使用者控制接口
3. * @author Administrator
4. *
5. */
6. public interface UserManager {
7.
8. public void addUser(String userId,String userName);
9. public void modifyUser(String userId,String userName);
10. public void delUser(String userId);
11. public String findUser(String userId);
12. }
實作類UserManagerImpl
1. /****
2. * 使用者管理真正的實作類
3. * @author Administrator
4. *
5. */
6. public class UserManagerImpl implements UserManager {
7.
8. /*****
9. * 添加使用者
10. */
11. public void addUser(String userId, String userName) {
12. "正在添加使用者,使用者為:"+userId+userName+"……");
13. }
14. /*****
15. * 删除使用者
16. */
17. public void delUser(String userId) {
18. "delUser,userId="+userId);
19. }
20. /***
21. * 查找使用者
22. */
23. public String findUser(String userId) {
24. "findUser,userId="+userId);
25. return userId;
26. }
27.
28. public void modifyUser(String userId, String userName) {
29. "modifyUser,userId="+userId);
30. }
31. }
1. import java.lang.reflect.InvocationHandler;
2. import java.lang.reflect.Method;
3. import java.lang.reflect.Proxy;
4.
5. public class LogHandler implements InvocationHandler {
6.
7. private Object targetObject;
8.
9. public Object newProxyInstance(Object targetObject) {
10. this.targetObject = targetObject;
11. return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
12. this);
13. }
14.
15. public Object invoke(Object proxy, Method method, Object[] args)
16. throws Throwable {
17. null;
18.
19. try {
20. "正在進行操作前的準備工作……");
21. //調用目标方法
22. ret = method.invoke(targetObject, args);
23. "操作成功,正在進行确認處理……");
24. catch (Exception e) {
25. e.printStackTrace();
26. "error-->>" + method.getName());
27. throw e;
28. }
29. return ret;
30. }
31. }
用戶端Client
1. public class Client {
2.
3. /**
4. * @param args
5. */
6. public static void main(String[] args) {
7. new LogHandler();
8. new UserManagerImpl());
9. "0001");
10. }
11. }
運作結果
時序圖
總結
動态代理模式通過使用反射,可以在運作期決定加載哪個類,避免了一個類對應一個代理的問題;同時,通過統一的invoke方法,統一了代理類對原函數的處理過程,使用動态代理很大程度上減少了重複的代碼,降低了維護的複雜性和成本。
//**********************************************
接口
package com.ygl.dynamicproxy;
public interface Subject {
public void request();
}
//*********************
package com.ygl.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 該代理類的内部屬性是Object類型,實際使用時通過該類的構造方法傳遞進來一個對象
* 此外,該類還重寫了invoke方法,該方法中的method。invoke其實就是被代理對象(真實對象)的将要執行的方法,
* 方法參數subject表示該方法屬于subject對象,通過動态代理類,我們可以在執行真實對象的方法前後加入自己的方法
* @author lenovo
*
*/
public class DynamicSubject implements InvocationHandler{
private Object subject;
public DynamicSubject(Object obj){
this.subject=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("bfore calling"+method);
method.invoke(subject, args);
System.out.println("after calling"+method);
return null;
}
}
//**************************************
package com.ygl.dynamicproxy;
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject");
}
}
//********************************
package com.ygl.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
RealSubject realSubject=new RealSubject();
InvocationHandler handler=new DynamicSubject(realSubject);
Class<?> clazz=handler.getClass();
System.out.println(clazz);
//下面的代碼一次性生成代理
//傳入真實角色實作的接口 realSubject.getClass().getInterfaces(),得到的subject是一個代理的執行個體class $Proxy0其實作了 realSubject.getClass().getInterfaces()這些接口
Subject subject=(Subject)Proxy.newProxyInstance(clazz.getClassLoader(), realSubject.getClass().getInterfaces(), handler);
System.out.println(subject.getClass());//class $Proxy0
subject.request();//此時會執行相應handler裡的invoke方法
}
}
//*******************
class com.ygl.dynamicproxy.DynamicSubject
bfore callingpublic abstract void com.ygl.dynamicproxy.Subject.request()
RealSubject
after callingpublic abstract void com.ygl.dynamicproxy.Subject.request()
class $Proxy0