首页 课程 师资 教程 报名

AOP代理模式的介绍

  • 2022-12-22 10:38:15
  • 314次 星辉

AOP的实现原理

当调用容器的getBean方法后,Spring查找对象后会判断该对象的方法是否被某个切面切中

如果没有切中,就创建原有类的对象

如果被切中了,再判断该类是否实现过任何接口

如果实现过接口,则通过JDK动态代理生成代理类,并创建对象

如果没有实现过接口,则通过CGLib动态代理生成代理类,并创建对象

例子

JDK自从1.3版本开始,就引入了动态代理,JDK的动态代理用起来非常简单,但是它有一个限制,就是使用动态代理的对象必须实现一个或多个接口 。如果想代理没有实现接口的类可以使用CGLIB包。先来看看GCLIB的具体使用,然后再对应代码深入理解。

在使用CGLIB时需引入cglib-nodep-2.1_3.jar包。

先来一个基础类,注意,这里没有对应的接口。

public class GreetingImpl { 
	public void sayHello(String name) {
		System.out.println("Hello! " + name);
	}
}

然后就是咱们定义的动态代理类

package com.tgb.sld.cglibproxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * CGLib动态代理类
 *
 * @author sunliduan 2015年5月26日 下午3:32:38
 */
public class CGLibDynamicProxy implements MethodInterceptor {
	// 定义被代理的对象
	private Object target; 
	// 根据被代理对象,创建代理类
	public Object createProxy(Object target) {
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());// 设置代理目标
		enhancer.setCallback(this);// 设置回调
		enhancer.setClassLoader(target.getClass().getClassLoader());
		return enhancer.create();
	} 
	// 通过代理类调用被代理类的方法或者特殊处理(如切入方法)
	@Override
	 public Object intercept(Object proxy, Method method, Object[] params,
	            MethodProxy methodProxy) throws Throwable {
		before();
		Object object= methodProxy.invoke(target, params);
		after();
		return object;
	} 
	private void before() {
		System.out.println("Before==通过CGLib动态代理把我加到被切方法之前");
	} 
	private void after() {
		System.out.println("After==通过CGLib动态代理把我加到被切方法之后");
	} 
}

其实在代理类中和JDK动态代理实现的功能或者是原理来说,是很类似的:首先定义一个Object类型的被代理对象;然后根据被代理对象,创建代理类;最后通过代理类调用被代理类的方法或者特殊处理(如切入方法)。

客户端的调用代码如下:

<span style="font-size:18px;">package com.tgb.sld.cglibproxy;
public class Client {
	public static void main(String[] args) { 
		CGLibDynamicProxy cgLibDynamicProxy=new CGLibDynamicProxy();
		GreetingImpl greetingImpl= (GreetingImpl) cgLibDynamicProxy.createProxy(new GreetingImpl());				
greetingImpl.sayHello("duanduan");		
	} 
}</span>

这样,我们基本上解决了JDK动态代理的局限-不能代理没有对应接口的类。CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。当然这些实际的功能是asm所提供的,asm又是什么?Java字节码操控框架,具体是什么大家可以查一查,cglib就是封装了asm,简化了asm的操作,实现了在运行期动态生成新的class。如果大家想了解更多相关知识,不妨来关注一下本站的Java星辉在线学习技术文档,里面还有更丰富的知识等着大家去学习,希望对大家能够有所帮助。

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交