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