基于CGLib(面向Class)的Spring AOP实现原理

Spring中,基于Dynamic Proxy是面向接口的动态代理实现,其代理对象必须是某个接口的实现。Dynamic Proxy通过在运行期构建一个此接口的动态实现类完成对目标对象的代理(相当于在运行期动态构造一个UserDAOProxy,完成对UserDAOImp的代理任务)。而如果目标代理对象并未实现任何接口,那么Dynamic Proxy就失去了创建动态代理类的基础依据。此时我们需要借助一些其他的机制实现动态代理机制。Spring中,引入了CGLib作为无接口情况下的动态代理实现。

CGLib与Dynamic Proxy的代理机制基本类似,只是其动态生成的代理对象并非某个接口的实现,而是针对目标类扩展的子类。换句话说,Dynamic Proxy返回的动态代理类,是目标类所实现的接口的另一个实现版本,它实现了对目标类的代理(如同UserDAOProxy与UserDAOImp的关系)。而CGLib返回的动态代理类,则是目标代理类的一个子类(代理类扩展了UserDAOImp类)。



与Dynamic Proxy中的Proxy和InvocationHandler相对应,Enhancer和MethodInterceptor在CGLib中负责完成代理对象创建和方法截获处理。
下面是通过CGLib进行动态代理的示例代码:

public class AOPInstrumenter implements MethodInterceptor {
    private static Log logger =
    LogFactory.getLog(AOPInstrumenter.class);
    private Enhancer enhancer = new Enhancer();

    public Object getInstrumentedClass(Class clz) {
           enhancer.setSuperclass(clz);
           enhancer.setCallback(this);
           return enhancer.create();
    }

    public Object intercept(
           Object o,
           Method method,
           Object[] methodParameters,
           MethodProxy methodProxy)
    throws Throwable {
           logger.debug("Before Method =>"+method.getName());
          
           Object result = methodProxy.invokeSuper(o, methodParameters);
          
           logger.debug("After Method =>"+method.getName());
          
           return result;
    }
}

测试代码:
AOPInstrumenter aopInst = new AOPInstrumenter();
UserDAOImp userDAO =
(UserDAOImp) aopInst.getInstrumentedClass(UserDAOImp.class);
User user = new User();
user.setName("Erica");
userDAO.saveUser(user);

Spring中,基于CGLib的AOP实现位于:
org.springframework.aop.framework.Cglib2AopProxy

猜你喜欢

转载自maosheng.iteye.com/blog/1908504