JAVA动态静态代理

各种动态代理的区别

1、CglibAopProxy:在从容器中获取bean的时候,动态织入代码,动态构建字节码,采用ASM、javavssist组件修改,实现Cglib动态代理不需要接口去实现。

2、JdkDynamicAopProxy:动态构建字节码,采用ASM、javavssist组件修改,实现JDK动态代理需要接口去实现。

3、Aspectj:编译代码时,将目标代码的字节码织入代码,在Eclipse编译时就已经织入了,属于静态代理。

4、Instrumention:基于javaagent,类装载的时候动态拦截去修改。

动态代理原理

通过InvocationHandler接口,将代理对象、目标对象、代理逻辑连接一起。如下代码IUser属于代理对象,UserImpl属于目标对象,method.invoke(target, args);的前后属于代理逻辑。Proxy包含InvocationHandler,InvocationHandler包含目标对象,在执行目标对象时,动态织入代码逻辑,比如权限校验、日志记录。

一句话,目的就是生成一个UserImpl$Proxy,这个类的invoke包含了织入代码和调用目标对象的method.invoke方法

public class InvocationHandlerTest{
	public static void main(String[] args) {
		IUser user = (IUser)Proxy.newProxyInstance(InvocationHandlerTest.class.getClassLoader(), new Class[]{IUser.class}, new InvocationHandler(){
			UserImpl target = new UserImpl();// 目标方法
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("相当于@AspectJ的@Before"); //代理逻辑
				Object result = method.invoke(target, args);
				System.out.println("相当于@AspectJ的@After");
				return result;
			}
		});
		int sayHelloResult = user.sayHello();
		System.out.println("sayHelloResult="+sayHelloResult);
	}
}
//代理对象
interface IUser{
	int sayHello();
}
class UserImpl implements IUser{
	@Override
	public int sayHello() {
		System.out.println("hello!");
		return 0;
	}
}

java动态代理是在构建代理对象(IUser)的过程中构建一个新的class(UserImpl),过程如下:

1、Proxy基于代理接口(IUser)获取目标对象(UserImpl)

(1)、从缓存中获取

(2)、缓存没有,时使用ProxyGenerator重新构建目标对象(UserImpl)class字节码,这个字节码extends Proxy implments IUser,invoke方法包含了InvocationHandler的invoke方法里的所有逻辑

(3)、调用本地方法装载目标对象class字节码

(4)、通过Class.forName返回重新构建后的class对象

2、使用反射生成代理对象UserImpl

3、通过method.invoke(target, args);调用代理对象

源码调用栈:

.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
          Class<?> cl = getProxyClass0(loader, intfs);

                    WeakCache.get(loader, interfaces);

                    // ProxyGenerator重新构建目标对象(UserImpl)class字节码,这个字节码extends Proxy implments IUser,invoke方法包含了InvocationHandler的invoke方法里的所有逻辑

                    byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);

                    // 调用本地方法装载目标对象class字节码

                    native Class<?> defineClass0(ClassLoader loader, String name, byte[] b, int off, int len)

          Constructor<?> cons = cl.getConstructor(constructorParams);

          cons.newInstance(new Object[]{h});

应用协议代理

思路:

1、重写HttpURLConnection

2、重写HttpStreamHandlerFactory

3、重写Handler

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值