spring AOP (6) 基础知识-cglib代理

JDK的动态代理只能针对接口来实现,由Proxy.newProxyInstance()第二个参数能很清楚地意识到这一点。面向接口编程肯定有它自己的好处,但是如果很小很小的一个项目,我们要对每个业务类创建一个接口,也并不一定是件好事吧。

如果不创建接口,而要实现代理,我们需要用到cglib,它是一个第三方的jar包,需要额外导入。

cglib采用非常底层的字节码技术,可以为代理对象创建一个子类,并且在子类中采用方法拦截的技术,拦截所有父类方法的调用,并且织入横切逻辑。

注意,既然是为父类创建一个子类,那么final修饰的方法是不能继承的,所以final修饰的方法是不会被织入横切逻辑的。

目标类:

package spring3.aop.aop4;

public class Target {

	public void do1() {
		System.out.println("Target.do1()");
	}

	public void do2(String str) {
		System.out.println("Target.do2(" + str + ")");
	}

	public void exe1() {
		System.out.println("Target.exe1()");
	}

	public void exe2(String str) {
		System.out.println("Target.exe2(" + str + ")");
	}

	public final void exe3() {
		System.out.println("Target.exe3");
	}
}

 创建代理类 CglibProxy

package spring3.aop.aop4;

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 CglibProxy implements MethodInterceptor {

	private Enhancer enhancer = new Enhancer();

	public Object getProxy(Class<?> cls) {
		// 设定被代理类(目标类)
		enhancer.setSuperclass(cls);
		// 实例化代理类
		enhancer.setCallback(this);
		return enhancer.create();
	}

	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("----START----");
		Object result = proxy.invokeSuper(obj, args);
		System.out.println("----END----");
		return result;
	}
}

 测试类:

package spring3.aop.aop4;

public class ProxyMain {

	public static void main(String[] args) {

		CglibProxy proxy = new CglibProxy();
		Target childTarget = (Target) proxy.getProxy(Target.class);
		childTarget.do1();
		childTarget.do2("test");
		childTarget.exe1();
		childTarget.exe2("test");
		childTarget.exe3();
	}
}

 测试结果:

----START----
Target.do1()
----END----
----START----
Target.do2(test)
----END----
----START----
Target.exe1()
----END----
----START----
Target.exe2(test)
----END----
Target.exe3

 这部分没有什么要讲的,大家知道就可以了。

注意,加载cglib时间比jdk的反射时间要长,如果应用中频繁的动态生成新的代理,不建议使用cglib,这个根据具体需求自己判断。

spring的aop是通过jdk动态代理或者cglib动态代理为目标bean织入横切逻辑的。

猜你喜欢

转载自xieyan30.iteye.com/blog/1845071