每日一个技术点之动态代理

发布于:2023-01-14 ⋅ 阅读:(254) ⋅ 点赞:(0)

cglib和jdk 动态代理的区别?

  1. cglib 用的是asm字节码框架,而jdk用的是反射机制,这就导致了cglib创建对象慢但执行速度快 jdk创建对象快,但执行相对较慢
  2. 经过反编译发现jdk 动态代理是创建了一个继承了Proxy类的代理类并实现了接口,($class0 extends Proxy implements interfaceA )其中class0中聚合了很多接口中的方法,通过method.invoke反射机制实现调用。
  3. cglib 动态代理无需依赖接口,而需要依赖cglib库,但是jdk则需要依赖接口,并且不依赖库即可实现。

用途:一般对于web应用来说,jdk动态代理用途较广,针对没有目标接口的要代理的类则可以选择cglib动态代理

------------------------------- 2022.8.17--------------------------------------------------------------------------

如何使用?(以jdk 动态代理为例)

jdk动态代理强依赖于接口,所以我们首先需要创建一个接口


/**
 * 自定义接口
 * @author lenovo
 *
 */
public interface MyActionInterface {
	void myAction(String username);
}

接口都是要实现的,因此之后创建一个实现类

public class MyActionImpl implements MyActionInterface{

	@Override
	public void myAction(String username) {
		System.out.println("action = " + username);
	}
}

最关键的一步来了,创建proxy代理handler

/**
 * jdk 动态代理
 * @author 章鱼哥
 *
 */
public class MyProxy implements InvocationHandler{
	/**
	 * 代理对象
	 */
	private Object target;
	
	/**
	 * 直接传入类信息
	 * @param target
	 */
	public MyProxy(Object target) {
		this.target = target;
	}
	
	/**
	 * 通过class字节码获取类信息
	 * @param targetClass
	 */
	public MyProxy(Class<?> targetClass) {
		try {
			this.target = targetClass.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 通过jdk 动态代理创建对象,进行封装
	 */
	public Object newObject() {
		if (target == null) {
			throw new RuntimeException("代理对象为空");
		}
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		//预处理
		Object result = method.invoke(target, args);
		//处理结果
		return result;
	}
}

最后调用

public class ProxyTest {
	public static void main(String[] args) {
		//注意返回的代理对象为接口对象,需要用接口对象作为返回类型
		MyActionInterface impl = (MyActionInterface)new MyProxy(MyActionImpl.class)
				.newObject();
		impl.myAction("zyg");
	}
}

原理?源码?

https://baijiahao.baidu.com/s?id=1678997916718732701&wfr=spider&for=pc


网站公告

今日签到

点亮在社区的每一天
去签到