上高中的时候,看过最激励成长的电视剧就是《士兵突击》,里面一个很骄傲的连长说过一句话,以前一直觉得许三多不怎样,每天都在做一些小事,可是没想到,最后他却垒起来了一座大山。
知乎上有一句话叫,以现在人们努力程度之低,更本谈不上拼天赋,有时候认真做好每一件自己觉得对的事,也许就是最美的事
上一篇说了反射,那这时候就讲代理,因为代理是基于反射的。
代理有好几种,现在说说最常见的几个
1 jdk静态代理(设计模式)
public class StaticProxyHello implements IHelloService {
private IHelloService helloService = new HelloService();
public String sayHello(String message) {
beforeProcess();
String result = helloService.sayHello(message);
afterProcess();
return result;
}
private void beforeProcess(){
System.out.println("我是委托类方法处理之前要执行的方法。。。。");
}
private void afterProcess() {
System.out.println("我是委托类处理之后执行的方法。。。。");
}
}
这个是静态代理的核心类,那他做了什么,就是下面这些
静态代理的代理类 的意思其实是一个被代理类的增强类 可以在代理类基础上增加一些方法 而不改变被代理类的代码 这样在重构的时候 就可以减少代理的测试量 其实就是代理模式 一个委托类 一个代理类 一个被代理类 代理类里面实例化被代理类 方法调用时 首先调用代理类 接着调用被代理类 2 jdk动态代理
public class HelloProxyInvocationHandler implements InvocationHandler {
private Object obj;
public HelloProxyInvocationHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeProcess();
Object result = method.invoke(obj, args);
afterProcess();
return result;
}
private void beforeProcess() {
System.out.println("增加方法調用之前执行的额外操作...");
}
private void afterProcess() {
System.out.println("增加方法調用之后执行的额外操作...");
}
}
Jdk动态代理核心类 他并没有实现 对应的接口 要实现动态代理一定要实现InvocationHandler 这个是java反射包里面的 所以说动态代理的实现是反射
3 cglib动态代理
public class HelloInterceptor implements MethodInterceptor {
/**
* 用于生成 Cglib 动态代理类工具方法
* @param target 委托类
* @return
*/
public Object initCglib(Class target) {
Enhancer enhancer = new Enhancer();// 为代理类指定需要代理的类,也即是父类
enhancer.setSuperclass(target);// 设置方法拦截器回调引用,对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept() 方法进行拦截
enhancer.setCallback(this);// 获取动态代理类对象并返回
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
beforeProcess();
Object result = methodProxy.invokeSuper(o, args);
afterProcess();
return result;
}
private void beforeProcess() {
System.out.println("增加方法調用之前执行的额外操作...");
}
private void afterProcess() {
System.out.println("增加方法調用之后执行的额外操作...");
}
}
Cglib动态代理
jdk动态代理有一个硬性要求,就是一定要有一个接口,如果没有接口也要使用代理时,就要使用cglib了 cglib的实现原理是 在类的基础上增加一个子类,通过子类来实现,但也有一个缺点就是因为要子类实现 那么就一定有继承,而final修饰的类是不能被继承的,所以不能使用 已上就是三种常见的动态代理,那他们直接的联系是什么
静态代理 比较适合代理类比较少的 如果很多的话 就要写很多的代理类,哪怕他们执行相同的东西 而动态代理就是来解决生成代理类较多问题的,因为不同的接口对应的也可以是相同的代理类实现, 这里也可以理解,如果不同的接口,要在被代理类的方法前后加东西,静态代理就要写几个代理类,去 实现,因为一个静态代理类,只能实例一个被代理类的引用, 而动态代理,只需要一个公共的jdkProxy中写一个方法就可以了。 缺点就是必须要有接口,才能调用 cgli动态代理是继续asm字节码的,他更加底层,相对速度更快,但是他初始化创建的时间要比jdk动态代理长很多, 所以对于频繁创建的类,不能选择cglib动态代理
使用场景
最注明的就是mybatic的动态代理,还有就是设计模式中,如果想修改之间的类,也可以通过代理类在不修改之前的代码来处理