1 代理可以分为静态代理、动态代理,动态代理又可以分为 jdk 动态代理 和 cglib的动态代理。像spring框架的AOP的底层就使用了两种动态代理的技术。更准确来说如果如果有被调用的方法继承了接口,那么更多的是jdk动态代理,如果没有那么多数是cglib动态代理。
2动态代理,jdk动态代理: 利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对象),代理的是接口(Interfaces),不是类(Class),也不是抽象类。在运行时才知道具体的实现,spring aop就是此原理。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
newProxyInstance,方法有三个参数:
loader: 用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:动态代理方法在执行时,会调用h里面的invoke方法去执行
要继承的接口
public interface IVehical {
void run();
}
//car继承IVehical
public class Car implements IVehical {
@Override
public void run() {
System.out.println("Car会跑,还很快");
}
}
//调用方法
public class App {
public static void main(String[] args) {
IVehical car = new Car();
IVehical vehical = (IVehical) Proxy.newProxyInstance(car.getClass().getClassLoader(), Car.class.getInterfaces(), new VehicalInvacationHandler(car));
vehical.run();
}
}
//动态代理
public class VehicalInvacationHandler implements InvocationHandler {
private final IVehical vehical;
public VehicalInvacationHandler(IVehical vehical){
this.vehical = vehical;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用之前执行");
Object invoke = method.invoke(vehical, args);
return invoke;
}
}
invoke三个参数:
proxy:就是代理对象,newProxyInstance方法的返回对象
method:调用的方法
args: 方法中的参数
3cglib的动态代理:没有接口的时候,在spring boot时使用
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
public class TargetUser {
public static void main(String[] args) {
Target target = (Target) TargetProxy.getProxy(new Target());
target.method1();
}
}
public class Target {
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
public class TargetProxy {
static <T> Object getProxy(T t) {
Enhancer en = new Enhancer(); //帮我们生成代理对象
en.setSuperclass(t.getClass());//设置要代理的目标类
en.setCallback(new MethodInterceptor() {//代理要做什么
@Override
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("执行方法前。。。");
//调用原有方法
Object invoke = methodProxy.invokeSuper(object, args);
// Object invoke = method.invoke(t, args);// 作用等同与上面。
System.out.println("执行方法后。。。");
return invoke;
}
});
return en.create();
}
}
4 静态代理:在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。
//接口代码
public interface TargetInteface {
void method1();
void method2();
int method3(Integer i);
}
//要被代理的方法
public class Target implements TargetInteface {
@Override
public void method1() {
System.out.println("method1 running ...");
}
@Override
public void method2() {
System.out.println("method2 running ...");
}
@Override
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
//静待代理
public class TargetProxy implements TargetInteface {
@Override
public void method1() {
System.out.println("执行方法前...");
new Target().method1();
System.out.println("执行方法后...");
}
@Override
public void method2() {
System.out.println("执行方法前...");
new Target().method2();
System.out.println("执行方法后...");
}
@Override
public int method3(Integer i) {
System.out.println("执行方法前...");
int method3 = new Target().method3(i);
System.out.println("执行方法后...");
return method3;
}
}
//调用静态代理
public static void main(String[] args) {
TargetInteface target = new TargetProxy();
target.method1();
System.out.println("-----------------------------");
target.method2();
System.out.println("-----------------------------");
System.out.println(target.method3(3));
}
TargetInteface target = new TargetProxy()创建一个代理对象,让代理对象加上相应的处理来实现静态代理和链表很像,很简单不多说。