SpringAop中的jdk动态代理技术和cglib动态代理技术

1、Spring Aop中使用到了动态代理技术,对于jdk动态代理,要求必须代理接口,底层是java的反射机制,对于类,使用cglib字节码增强来动态代理


2、设计模式中简单的代理模式实现


3、jdk动态代理的实现方法

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

//实现了InvocationHandler接口并实现了它的invoke方法
public class ProxyTest implements InvocationHandler{

	//目标代理对象
	private Object target;
	public ProxyTest(){
	}

	//带参的构造函数,用于传递目标代理对象
	public ProxyTest(Object target){
		this.target = target;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("执行方法前");
		//代理对象执行对应的方法 在前面后后面都加上了代码,这是Aop的一种实现方式,面向切面编程
		method.invoke(target, args);
		System.out.println("执行方法后");
		return target;
	}
	
	public static void main(String[] args) {
		//创建需要被代理的对象
		Sky sky1 = new ProxyTest().new SkyImpl();
		//创建代理对象
		ProxyTest proxyTest = new ProxyTest(sky1);
		//生成代理对象
		Sky sky = (Sky)Proxy.newProxyInstance(SkyImpl.class.getClassLoader(), SkyImpl.class.getInterfaces(),proxyTest );
		//执行方法
		sky.rain();
	}
	
	interface Sky{
		void rain();
	}
	class SkyImpl implements Sky{
		public void rain() {
			System.out.println("天下雨了");
		}
	}
}


4、运行结果



5、反编译过后,实际上是代理类继承了Proxy类并且实现了对应代理的接口,由于java只能支持单继承,所以jdk代理只适用于代理接口,例如 $ProxyClass extends Proxy implements Sky


6、cglib动态代理案例,需要在maven中添加cglib的依赖包

import java.lang.reflect.Method;

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

public class CglibTest {

	public static void main(String[] args) {
		Enhancer enhancer = new Enhancer();
		//设置需要代理的类
		enhancer.setSuperclass(HelloServiceImpl.class);
		//设置回调方法
		enhancer.setCallback(new HelloMethodInterceptor());
		//创建代理对象
		HelloServiceImpl helloServiceImpl = (HelloServiceImpl)enhancer.create();
		//调用代理对象的方法
		helloServiceImpl.sayHello();
	}
	
}

//被代理的类
class HelloServiceImpl{
	
	public void sayHello(){
		System.out.println("Hello,World!");
	}
}

class HelloMethodInterceptor implements MethodInterceptor{
	
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		System.out.println("方法调用前");
		//执行代理对象的方法 在前面后面加通知都可以
		methodProxy.invokeSuper(obj, args);
		System.out.println("方法调用后");
		return obj;
	}
}


7、执行的结果


8、cglib是一种字节码增强的动态代理技术,它代理的是类,而具体的实现是代理类继承了需要被代理的类,并增强了它的方法 $ProxyClass extends HelloServiceImpl  注意:cglib不能代理final修饰的类,也不能代理final修饰的方法,因为不能重写

猜你喜欢

转载自blog.csdn.net/qq_31489805/article/details/79670768
今日推荐