Spring学习笔记五(JDKProxy和cglibProxy的区别)

 

 1.前言

上一篇博客讲解了一下Spring中的AOP,而这篇博客来剖析下Spring实现AOP的两种机制:JDKProxy和cglibProxy两种动态代理


 2.JDKProxy动态代理

JDK动态代理,为接口实现的对象创建代理。具体详见源码。

<span style="font-family:SimSun;font-size:18px;">package com.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyJdk implements InvocationHandler {

	//代理的接口
	private MyInterface m;
	public MyInterface createJDKProxyObject(MyInterface m) {
		this.m=m;
		// 需要类加载器
		ClassLoader loader = m.getClass().getClassLoader();
		// 实现的接口
		Class[] interfaces = m.getClass().getInterfaces();
		// 方法拦截
		return	(MyInterface) Proxy.newProxyInstance(loader, interfaces, this);
		
	}

	//当方法执行的时候,进行拦截
	//proxy:生成的代理对象
	//method:拦截的执行方法
	//args:拦截的执行方法时使用的参数
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//输出拦截的方法
		System.out.println("没几怕,啊");
		//输出参数
		for(Object obj:args){
			System.out.println(obj);
		}
		//调用真实类的方法
		Object obj=method.invoke(m, args);
	
		return 102;
	}
}
</span>

分析

1.先是通过类加载器,从内存中获取接口

2.接着拿到被代理类所实现的接口

3.然后通过代理类反射创建代理对象


 3.cglibProxy动态代理

针对于非接口实现的对象,创建的是类的代理类,然后由代理类创建对象。




分析

1.首先在内存中创建一个类的字节码

2.然后为该类指定继承的父类

3.最后为调用被代理类的子类


源码

<span style="font-family:SimSun;font-size:18px;">package com.Cglib;

import java.lang.reflect.Method;

import javax.security.auth.callback.Callback;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class MyCglibProxyObject implements MethodInterceptor{
	//提供一个方法用于创建Animal类的代理对象
	
	public Animal createCglibProxyObject(){
		//在内存中创建一个动态类的字节码
		Enhancer enhancer=new Enhancer();//此时并没有做继承
		//为其指定父类
		//除了完成继承关系外,还将父类所有的方法名反射过来,并在自己的类中
		//创建了这些方法
		enhancer.setSuperclass(Animal.class);
		
		enhancer.setCallback(this);
		//使用该类创建对象
		return (Animal)enhancer.create();
	}

	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		if(method.getName().endsWith("eat")){
			System.out.println("吃前的动作");
		}
		//走父类的调用
		return methodProxy.invokeSuper(proxy, args);
	}
}
</span>


 4.小结

Spring AOP的底层就是通过JDK动态代理或者cglib动态代理技术为目标Bean横向织入。

如果目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。

如果目标对象没有实现任何接口,spring使用cglib库生成目标对象的子类。

程序中应该优先对接口创建代理,便于程序解耦维护。



评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值