动态代理

202 阅读1分钟

cglib先来

导包

  <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>
        </dependency>

先写一个被代理类

package com.baron.yueapi.entity;

import lombok.Data;

import java.util.Random;

/**
 * @author 吴洋
 */
@Data
public class Tank {


	public void move(){
		System.out.println("calfal");
		try {
			Thread.sleep(new Random().nextInt(10000));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

再来一个

callback 主义调用的是父类发方法 ,记得有返回值的

package com.baron.yueapi.entity;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CallBack implements MethodInterceptor {
	@Override
	public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
		long l = System.currentTimeMillis();
		Object invoke = methodProxy.invokeSuper(o, objects);
		System.out.println(System.currentTimeMillis()-l);
		return invoke;
	}
}

最后测试

  Enhancer enhancer=new Enhancer();
      enhancer.setSuperclass(Tank.class);
      enhancer.setCallback(new CallBack());
      Tank o = (Tank) enhancer.create();
      o.move();

动态jdk代理

注意把对象传进去 不让拿不到,对象就不知道给那个对象传值了, 这个invoke是通过接口生产代理类后,调用的,比如这个add方法

image.png

h指的是invocationHanlder

image.png 会根据接口生产一个类 他具有所以该接口的方法以及一些常用方法,并且从对象手里,获取到调用权,既然有了对象, 有了方法,就可以通过反射出结果 并返回..

最后还是通过invoke方法,里面我们自己实现的反射去调用方法

Tank tank = new Tank();
		movable nmsl = (movable) Proxy.newProxyInstance(Tank.class.getClassLoader(), new Class[]{movable.class}, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("nmsl");
				Object invoke = method.invoke(tank, args);


				return invoke;
			}
		});
		nmsl.fuck();