是SpringAOP的底层【SpringAOP 、SpringMVC】
-
静态代理
-
动态代理
10.1、静态代理
角色分析
-
抽象角色:一般使用接口或抽象类来实现
-
真实角色:被代理的角色
-
代理角色:代理真实角色,在代理后一般会做一些附属操作
-
客户:访问代理的人
代码:
-
接口
public interface Rent { public void rent(); }
-
真实角色
public class Host implements Rent { @Override public void rent() { System.out.println("房东租房"); } }
-
代理角色
public class proxy implements Rent{ private Host host; public proxy(Host host) { this.host = host; } public void rent() { host.rent(); fee(); hetong(); kanfang(); } public void fee(){ System.out.println("中介费"); } public void hetong(){ System.out.println("签合同"); } public void kanfang(){ System.out.println("看房"); } }
-
客户
public class Client { public static void main(String[] args) { proxy proxy = new proxy(new Host()); proxy.rent(); } }
-
静态代理缺点:
-
每一个真实角色就会产生一个代理角色,代码量翻倍
-
静态代理优点:
-
使真实角色的操作更纯粹,不用关注一些公共业务
-
公共业务交给代理,实现业务分工
-
公共业务放生拓展时,方便集中管理
10.2、动态代理
-
与静态代理角色一样
-
代理类是动态生成的
-
分为两大类
-
基于接口的动态代理----JDK动态代理【在此使用】
-
基于类的动态代理----cglib
-
java字节码实现---javasist
-
了解两个类:
-
Proxy:生成得到代理类
-
InvocationHandle:调用代理实例,并返回结果
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
/* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class<?>[] { Foo.class },
handler);*/
//生成得到代理类
public Object getproxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//反射机制实现
log(method.getName());
return method.invoke(target,args);
}
public void log(String msg)
{
System.out.println("执行了"+msg+"方法");
}
}
public static void main(String[] args) {
//真实角色
Host host=new Host();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
//通过调用程序处理角色来解决我们要调用的接口对象
handler.setTarget(host);
//proxy是动态生成的
Rent proxy = (Rent) handler.getproxy();
proxy.rent();
}
动态代理的优点
-
使真实角色的操作更纯粹,不用关注一些公共业务
-
公共业务交给代理,实现业务分工
-
公共业务放生拓展时,方便集中管理
-
一个动态代理类代理的是一个接口,一般就是对应的一类业务
-
一个动态代理类可以代理多个类,只要是实现了同一个接口