备:修改以前文章
为什么有代理模式:
- 当用户本身不想去做这件事情时,委托代理人【中介】,来帮忙完成,并可以做一些额外业务
- 当过往业务接口需要添加功能,而不改动过往代码时,用代理类来完成,实际业务,并做方法增强。
–公共接口(抽象角色),一类业务接口
public interface Subject {
void vist();
}
–实际对象 (被代理对象,实际业务)
public class Real implements Subject {
@Override
public void toDo() {
System.out.println("实际角色,要做的事");
}
}
–代理对象,代理对象需要完成真实对象得业务,也得实现同一接口。
public class CurProxy implements Subject {
private Subject subject;
public CurProxy(Subject subject) {
this.subject = subject;
}
@Override
public void toDo() {
before();
subject.toDo();
after();
}
private void before(){
System.out.println("方法执行前");
}
private void after(){
System.out.println("方法执行前");
}
}
–客户端 测试
public class Client {
public static void main(String[] args) {
//new 代理对象,实际执行得真实业务,并做方法增强
Subject subject = new CurProxy(new Real());
subject.toDo();
}
}
静态代理:
- 缺:每一类业务就需要一个实际得代理类
动态代理简述:
- 动态指得是,
代理类
得动态生成.jdk动态代理
运用反射由jdk生成代理类,生成的$Proxy0
extends Proxy implements Subject
所以只能代理接口
,this.h.invoke(this, m3, new Object[] { paramString });
反射执行实际业务方法。cglib
动态代理,则代理可以类
,继承真实public class Real$$EnhancerByCGLIB$$4612f55d extends Real implements Factory
- 动态生成一个要
代理类的子类
,子类重写
要代理的类的所有不是final
的方法- 在子类中采用
方法拦截
的技术拦截所有父类方法的调用,顺势织入横切逻辑;var10000.intercept(this, CGLIB$toDo$0$Method, CGLIB$emptyArgs, CGLIB$toDo$0$Proxy);
在这里插入代码片
–jdk代理类:
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
//生成代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(object, args);
after();
return invoke;
}
private void before(){
System.out.println("方法执行前");
}
private void after(){
System.out.println("方法执行前");
}
}
–客户端 测试
public class ProxyClient {
public static void main(String[] args) {
//生产代理类
Subject subject = new Real();
//默认jdk代理,只代理接口
DynamicProxy dynamicProxy = new DynamicProxy(subject);
//通过调用程序处理角色来处理我们要调用的接口对象
Subject proxy = (Subject)dynamicProxy.getProxy();
proxy.toDo();
}
}
–cglib代理类:
public class Real {
public void toDo() {
System.out.println("实际角色,要做的事");
}
}
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor{
// 根据一个类型产生代理类
public Object CreatProxyedObj(Class<?> clazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable{
// 这里增强
before();
Object o = arg3.invokeSuper(arg0, arg2);
after();
return o;
}
private void before(){
System.out.println("方法执行前");
}
private void after(){
System.out.println("方法执行前");
}
}
public static void main(String[] args) {
CglibProxy proxy2 = new CglibProxy();
//生存得real,拦截执行方法增强
Real real = (Real)proxy2.CreatProxyedObj(Real.class);
real.toDo();
}