43、Java动态代理一——动态类Proxy的使用
1.什么是動態(tài)代理?
答:動態(tài)代理可以提供對另一個對象的訪問,同時隱藏實際對象的具體事實。代理一般會實現(xiàn)它所表示的實際對象的接口。代理可以訪問實際對象,但是延遲實現(xiàn)實際對象的部分功能,實際對象實現(xiàn)系統(tǒng)的實際功能,代理對象對客戶隱藏了實際對象??蛻舨恢浪桥c代理打交道還是與實際對象打交道。
2.為什么使用動態(tài)代理?
答:因為動態(tài)代理可以對請求進行任何處理
3.使用它有哪些好處?
答:因為動態(tài)代理可以對請求進行任何處理
4.哪些地方需要動態(tài)代理?
答:不允許直接訪問某些類;對訪問要做特殊處理等
?
目前Java開發(fā)包中包含了對動態(tài)代理的支持,但是其實現(xiàn)只支持對接口的的實現(xiàn)。 其實現(xiàn)主要通過java.lang.reflect.Proxy類和java.lang.reflect.InvocationHandler接口。?
Proxy類主要用來獲取動態(tài)代理對象,InvocationHandler接口用來約束調(diào)用者實現(xiàn)
以下為模擬案例,通過動態(tài)代理實現(xiàn)在方法調(diào)用前后向控制臺輸出兩句字符串
目錄結(jié)構(gòu)
<br/>
定義一個HelloWorld接口
1 package com.ljq.test;2
3 ?/**
4 * 定義一個HelloWorld接口
5 *
6 * @author jiqinlin
7 *
8 */
9 ?publicinterface HelloWorld {
10 publicvoid sayHelloWorld();
11 }
<br/>
類HelloWorldImpl是HelloWorld接口的實現(xiàn)
1 package com.ljq.test;2
3 ?/**
4 * 類HelloWorldImpl是HelloWorld接口的實現(xiàn)
5 *
6 * @author jiqinlin
7 *
8 */
9 ?publicclass HelloWorldImpl implements HelloWorld{
10
11 publicvoid sayHelloWorld() {
12 System.out.println("HelloWorld!");
13 }
14
15 }
HelloWorldHandler是 InvocationHandler接口實現(xiàn)
1 package com.ljq.test;2
3 ?import java.lang.reflect.InvocationHandler;
4 ?import java.lang.reflect.Method;
5
6 ?/**
7 * 實現(xiàn)在方法調(diào)用前后向控制臺輸出兩句字符串
8 *
9 * @author jiqinlin
10 *
11 */
12 ?publicclass HelloWorldHandler implements InvocationHandler{
13 //要代理的原始對象
14 ?private Object obj;
15
16 public HelloWorldHandler(Object obj) {
17 super();
18 this.obj = obj;
19 }
20
21 /**
22 * 在代理實例上處理方法調(diào)用并返回結(jié)果
23 *
24 * @param proxy 代理類
25 * @param method 被代理的方法
26 * @param args 該方法的參數(shù)數(shù)組
27 */
28 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
29 Object result =null;
30 //調(diào)用之前
31 ? doBefore();
32 //調(diào)用原始對象的方法
33 result=method.invoke(obj, args);
34 //調(diào)用之后
35 doAfter();
36 return result;
37 }
38
39 privatevoid doBefore(){
40 System.out.println("before method invoke");
41 }
42
43 privatevoid doAfter(){
44 System.out.println("after method invoke");
45 }
46
47 }
測試類
package com.ljq.test;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
publicclass HelloWorldTest {
publicstaticvoid main(String[] args) {
HelloWorld helloWorld=new HelloWorldImpl();
InvocationHandler handler=new HelloWorldHandler(helloWorld);
//創(chuàng)建動態(tài)代理對象
HelloWorld proxy=(HelloWorld)Proxy.newProxyInstance(
helloWorld.getClass().getClassLoader(),
helloWorld.getClass().getInterfaces(),
handler);
proxy.sayHelloWorld();
}
}
運行結(jié)果為:
案例二
Calculator.java
1 import java.math.BigDecimal; 2 3 4 public interface Calculator { 5 6 //加法 7 BigDecimal add(String a,String b); 8 9 //減法 10 BigDecimal sub(String a,String b); 11 12 //乘法 13 BigDecimal mul(String a,String b); 14 15 //除法 16 BigDecimal div(String a,String b); 17 }?
SimpleCalculator.java
1 import java.math.BigDecimal; 2 3 4 public class SimpleCalculator implements Calculator{ 5 6 @Override 7 public BigDecimal add(String a, String b) { 8 9 BigDecimal n1=new BigDecimal(a); 10 BigDecimal n2=new BigDecimal(b); 11 12 return n1.add(n2); 13 } 14 15 @Override 16 public BigDecimal sub(String a, String b) { 17 BigDecimal n1=new BigDecimal(a); 18 BigDecimal n2=new BigDecimal(b); 19 20 return n1.subtract(n2); 21 } 22 23 @Override 24 public BigDecimal mul(String a, String b) { 25 BigDecimal n1=new BigDecimal(a); 26 BigDecimal n2=new BigDecimal(b); 27 28 return n1.multiply(n2); 29 } 30 31 @Override 32 public BigDecimal div(String a, String b) { 33 BigDecimal n1=new BigDecimal(a); 34 BigDecimal n2=new BigDecimal(b); 35 36 return n1.divide(n2); 37 } 38 39 }?
SimpleCalculatorLoggingProxy.java
1 import java.lang.reflect.InvocationHandler; 2 import java.lang.reflect.Method; 3 import java.lang.reflect.Proxy; 4 5 6 public class SimpleCalculatorLoggingProxy { 7 8 private Calculator target; 9 10 public SimpleCalculatorLoggingProxy(Calculator target){ 11 this.target=target; 12 } 13 14 public Calculator getProxy(){ 15 Calculator proxy=null; 16 17 // 18 ClassLoader loader=target.getClass().getClassLoader(); 19 20 Class[] interfaces=new Class[]{Calculator.class}; 21 22 InvocationHandler handle=new InvocationHandler() { 23 24 @Override 25 public Object invoke(Object proxy, Method method, Object[] args) 26 throws Throwable { 27 System.out.println("正在執(zhí)行"+method.getName()+"方法,參數(shù)為"+args[0]+","+args[1]); 28 return method.invoke(target, args); 29 } 30 }; 31 32 proxy= (Calculator) Proxy.newProxyInstance(loader, interfaces, handle); 33 return proxy; 34 } 35 36 }?
測試代碼:
1 Calculator target=new SimpleCalculator(); 2 3 Calculator proxy=new SimpleCalculatorLoggingProxy(target).getProxy(); 4 5 System.out.println(proxy.add("1", "2")); 6 7 System.out.println(proxy.div("3", "2"));?
輸出結(jié)果:
正在執(zhí)行add方法,參數(shù)為1,2
3
正在執(zhí)行div方法,參數(shù)為3,2
1.5
轉(zhuǎn)載于:https://www.cnblogs.com/caoyc/p/5627624.html
總結(jié)
以上是生活随笔為你收集整理的43、Java动态代理一——动态类Proxy的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原创:姜子牙身为丞相,死后不久,周文王为
- 下一篇: 一次优化小例子