我们知道JDK动态代理只能够代理实现了接口的类,而对于没有实现接口的类,jdk就显得无能为力.这种情况下,我们就选择使用cglib来为指定的目标类进行代理,它为目标类生成一个子类,然后覆盖其中的方法实现增强.
cglib如何实现代理,我们来看一段源码.
没有实现接口的类:
public class GreetingImpl {
public void sayHello(String name) {
System.out.println("Hello! " + name);
}
}
cglib代理类:
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 ghy
* version 3.0.0 , 2015年5月23日 下午3:37:40
*/
public class CGLibDynamicProxy implements MethodInterceptor {
//用单例模式创建代理对象
private static CGLibDynamicProxy instance = new CGLibDynamicProxy();
private CGLibDynamicProxy() {
}
public static CGLibDynamicProxy getInstance() {
return instance;
}
//得到代理的方法
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
}
//拦截被代理类的方法,在前后分别执行before()和after()方法
@Override
public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before();
Object result = proxy.invokeSuper(target, args);
after();
return result;
}
//拦截的方法执行前插入的方法
private void before() {
System.out.println("Before");
}
//拦截的方法执行后插入的方法
private void after() {
System.out.println("After");
}
}
Client客户端:
public class Client {
public static void main(String[] args) {
GreetingImpl greetingImpl = CGLibDynamicProxy.getInstance().getProxy(GreetingImpl.class);
greetingImpl.sayHello("Jack");
}
}
运行结果:
现在,有了jdk和cglib代理,动态地生成代理对象并执行我们想要插入的方法已经不是难事.可是,我们看到以上所有要插入的代码都写死在了代理类中,这是不科学的.我们的目标是,各种业务是独立的,各种服务诸如日志/权限/工作流等也都是独立的,通过代理将二者动态地联合起来,达到我们想要的结果.所以,AOP的实现还需要改进.因为到目前为止,我们所做的还不是最灵活的AOP.
原文:http://blog.csdn.net/zhuanzhe117/article/details/46124579