当调用容器的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大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习