- 方法的作用: 在運行時,動態創建一組指定的街口的實現類對象。(在運行時,創建實現了指定的一組接口的對象)
interface A {
}
interface B {
}
Object o = 方法(new Class[]{A.class, B.class})
//o 實現了A和B兩個接口
- Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h);
package pers.demo1.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() {
/*
* 三大參數
* 1. ClassLoader
* 方法需要動態生成一個類,這個類實現了 A, B 接口,然後創建了這個類的對象
* 需要生成一個類,這個類也需要加載到方法區中,ClassLoader 來加載
*
* 2. Class[] interfaces
* 他是要實現的接口們
*
* 3. InvocationHandler
* 他是調用處理器
*
* 代理對象的實現的所有接口中的方法,內容都是調用 InvocationHandler 的 invoke() 對象
*/
ClassLoader loader = this.getClass().getClassLoader();
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("你好動態代理");
return "xxx";
}
};
// 使用三大參數創建代理對象
Object o = Proxy.newProxyInstance(loader, new Class[]{A.class, B.class}, h);
//強轉成 A 和 B 類型成功
A a = (A) o;
B b = (B) o;
// a.a();
// a.aa();
// b.b();
// b.bb();
// System.out.println(o.getClass().getName());
Object result = a.aaa("hello", 100);
System.out.println(o);
}
}
interface A {
public void a();
public void aa();
public Object aaa(String s1, int i);
}
interface B {
public void b();
public void bb();
}
AOP(面向切面編程),他與裝飾者模式有點相似,他比裝飾者模式還要靈活
public Object invoke(Object proxy, Method method, Object[] args);
- invoke() 方法在什麼時候被調用
- 在代理對象創建時? 錯誤的
- 在調用代理對象所實現接口中的方法時? 正確的
- Object proxy: 當前對象,即代理對象,在調用誰的方法
- Method method: 當前被調用的方法 (目標方法)
- Object[] args: 實參
- 目標對象: 被增強的對象
- 代理對象: 需要目標對象,然後在目標對象上添加了增強後的對象
- 目標方法: 增強的內容
- 代理對象 = 目標對象 + 增強
//Waiter.java
package pers.demo2.test;
//服務員
public interface Waiter {
//服務
public void serve();
}
//ManWaiter.java
package pers.demo2.test;
public class ManWaiter implements Waiter {
@Override
public void serve() {
System.out.println("服務中...");
}
}
//Demo2.java
package pers.demo2.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class Demo2 {
@Test
public void fun1() {
Waiter manWaiter = new ManWaiter(); //目標對象
//給出三個參數來創建方法,得到代理對象
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = {Waiter.class};
InvocationHandler h = new WaiterInvocationHandler(manWaiter); //參數 manWaiter 表示目標對象
//得到代理對象,代理對象就是在目標對象的基礎上進行了增強對象
Waiter waiterProxy = (Waiter) Proxy.newProxyInstance(loader, interfaces, h);
waiterProxy.serve(); //前面添加"您好",後面添加"再見"
}
}
class WaiterInvocationHandler implements InvocationHandler {
private Waiter waiter; //目標對象
public WaiterInvocationHandler(Waiter waiter) {
this.waiter = waiter;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println("您好");
this.waiter.serve(); //調用目標對象的目標方法
// System.out.println("再見");
return null;
}
}
//Waiter.java
package pers.demo3.test;
//服務員
public interface Waiter {
//服務
public void serve();
}
//ManWaiter.java
package pers.demo3.test;
public class ManWaiter implements Waiter {
@Override
public void serve() {
System.out.println("服務中...");
}
}
//BeforeAdvice.java
package pers.demo3.test;
/**
* 前置增強
* @author jack870131
*
*/
public interface BeforeAdvice {
public void before();
}
//AfterAdvice.java
package pers.demo3.test;
public interface AfterAdvice {
public void after();
}
//ProxyFactory.java
package pers.demo3.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 用來生成代理對象
* 他需要所有的參數
* - 目標對象
* @author jack870131
*
*/
/**
* 1. 創建代理工廠
* 2. 給工廠設置三樣東西:
* - 目標對象: setTargetObject(xxx);
* - 前置增強: setBeforeAdvice(該接口的實現)
* - 後置增強: setAfterAdvice(該接口的實現)
* 3. 調用 createProxy() 得到代理對象
* - 執行代理對象方法時
* - 執行 BeforeAdvice 的 before()
* - 目標對象的目標方法
* - 執行 AfterAdvice 的 after()
* @author jack870131
*
*/
public class ProxyFactory {
private Object targetObject; //目標對象
private BeforeAdvice beforeAdvice; //前置增強
private AfterAdvice afterAdvice; //後置增強
/**
* 用來生成代理對象
* @return
*/
public Object createProxy() {
/*
* 1. 給出三大參數
*/
ClassLoader loader = this.getClass().getClassLoader();
Class[] interfaces = targetObject.getClass().getInterfaces();
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
* 在調用代理對象的方法時會執行這裡的內容
*/
//執行前置對象
if(beforeAdvice != null) {
beforeAdvice.before();
}
Object result = method.invoke(targetObject, args); //執行目標對象的目標方法
//執行後置增強
if(afterAdvice != null) {
afterAdvice.after();
}
//返回目標對象的返回值
return result;
}
};
/*
* 2. 得到代理對象
*/
Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
return proxyObject;
}
public Object getTargetObject() {
return targetObject;
}
public void setTargetObject(Object targetObject) {
this.targetObject = targetObject;
}
public BeforeAdvice getBeforeAdvice() {
return beforeAdvice;
}
public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
this.beforeAdvice = beforeAdvice;
}
public AfterAdvice getAfterAdvice() {
return afterAdvice;
}
public void setAfterAdvice(AfterAdvice afterAdvice) {
this.afterAdvice = afterAdvice;
}
}
//Demo3.java
package pers.demo3.test;
import org.junit.Test;
/**
* 目標是讓目標對象和增強都可以切換
* @author jack870131
*
*/
public class Demo3 {
@Test
public void fun1() {
ProxyFactory factory = new ProxyFactory(); //創建工廠
factory.setTargetObject(new ManWaiter()); //設置目標對象
factory.setBeforeAdvice(new BeforeAdvice() { //設置前置增強
public void before() {
System.out.println("您好");
}
});
factory.setAfterAdvice(new AfterAdvice() { //設置後置增強
public void after() {
System.out.println("再見");
}
});
Waiter waiter = (Waiter) factory.createProxy();
waiter.serve();
}
}