动态代理
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");
}
}