動態代理
1、動態代理和靜態代理的角色是一樣的。
2、動態代理的代理類是動態生成的。
3、分爲兩類,一類基於接口動態代理和基於類的動態代理。
a)基於接口動態代理——jdk動態代理
b)基於類的動態代理——cglib
現在javassist來生成動態代理
4、jdk動態代理——Proxy類和InvocationHander接口
5、InvocationHandler是代理實例的調用處理程序實現的接口。
6、每個代理實例都具有一個關聯的調用處理程序。對代理實例調用方法時,將對方法調用進行編碼並將其指派到它的調用處理程序的invoke方法。
Object invoke(Object proxy,Method method,Object[] args)在代理實例上處理方法調用並返回結果。
在代理實例上處理方法調用並返回結果。在與方法關聯的代理實例上調用方法時,將在調用處理程序上調用此方法。
參數:
proxy——在其上調用方法的代理實例
method——對應於在代理實例上調用的接口方法的Method實例。Method對象的聲明類將是在其中聲明方法的接口,該接口可以是代理類賴以繼承方法的代理接口的超接口。
args——包含傳入代理實例上方法調用的參數值的對象數組,如果接口方法不使用參數,則爲null。基本類型的參數被包裝在適當基本包裝器類(如java.lang.Integer或java.lang.Boolean)的實例中。
返回:
從代理實例的方法調用返回的值。如果接口方法的聲明返回類型是基本類型,則此方法返回的值一定是相應基本包裝對象類的實例;否則,它一定是可分配到聲明返回類型的類型。如果此方法返回的值爲null並且接口方法的返回類型是基本類型,則代理實例上的方法調用將拋出NullPointerException。否則,如果此方法返回的值與上述接口方法的聲明返回類型不兼容,則代理實例上的方法調用將拋出ClassCastException。
Proxy提供用於創建動態代理類和實例的靜態方法,它還是由這些方法創建的所有動態代理類的超類。
Client.java
package cn.sxt.dynamicproxy;
public class Client {
public static void main(String[] args) {
Host host=new Host();
ProxyInovationHandler pih =new ProxyInovationHandler();
pih.setRent(host);
Rent proxy =(Rent)pih.getProxy();
proxy.rent();
}
}
Host.java
package cn.sxt.dynamicproxy;
public class Host implements Rent {
public void rent() {
System.out.println("房屋出租");
}
}
ProxyInovationHandler.java
package cn.sxt.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInovationHandler implements InvocationHandler{
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
/*
* 生成代理類
*/
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(), this);
}
/*
* proxy是代理類
* method 代理類的調用處理程序的方法對象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
seeHouse();
Object result =method.invoke(rent, args);
fare();
return result;
}
private void seeHouse() {
System.out.println("帶房客看房");
}
//收中介費
private void fare() {
System.out.println("收取中介費");
}
}
Rent.java
package cn.sxt.dynamicproxy;
public interface Rent {
public void rent() ;
}
ProxyInovationHandler.java
package cn.sxt.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInovationHandler implements InvocationHandler{
private Object target;//目標對象——真實對象
public void setTarget(Object target) {
this.target = target;
}
/*
* 生成代理類
*/
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
/*
* proxy是代理類
* method 代理類的調用處理程序的方法對象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
seeHouse();
Object result =method.invoke(target, args);
fare();
return result;
}
//看房
private void seeHouse() {
System.out.println("帶房客看房");
}
//收中介費
private void fare() {
System.out.println("收取中介費");
}
}
Client.java
package cn.sxt.dynamicproxy;
import cn.sxt.service.UserService;
import cn.sxt.service.UserServiceImpl;
public class Client {
public static void main(String[] args) {
UserService userService=new UserServiceImpl();
ProxyInovationHandler pih =new ProxyInovationHandler();
pih.setTarget(userService);
UserService proxy =(UserService)pih.getProxy();
proxy.search();
}
}
ProxyInovationHandler.java
package cn.sxt.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInovationHandler implements InvocationHandler{
private Object target;//目標對象——真實對象
public void setTarget(Object target) {
this.target = target;
}
/*
* 生成代理類
*/
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
/*
* proxy是代理類
* method 代理類的調用處理程序的方法對象
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
log(method.getName());
Object result =method.invoke(target, args);
return result;
}
public void log(String methodName) {
System.out.println("執行"+methodName+"方法");
}
}
到這裏動態代理就完成了.
一個動態代理一般代理某一類業務,一個動態代理可以代理多個類。
Client.java
package cn.sxt.dynamicproxy;
import java.util.ArrayList;
import java.util.List;
import cn.sxt.service.UserService;
import cn.sxt.service.UserServiceImpl;
public class Client {
public static void main(String[] args) {
// UserService userService=new UserServiceImpl();
// ProxyInovationHandler pih =new ProxyInovationHandler();
// pih.setTarget(userService);
// UserService proxy =(UserService)pih.getProxy();
// proxy.search();
ProxyInovationHandler ph =new ProxyInovationHandler();
ph.setTarget(new ArrayList());
List list =(List)ph.getProxy();
list.add("hello");
}
}