CGLib动态代理

来源:互联网 发布:怎样更改域名dns 编辑:程序博客网 时间:2024/06/05 18:21

http://blog.csdn.net/xiaohai0504/article/details/6832990


有这么一个没有实现到接口的业务类。需要对save()业务方法进行控制。

package cn.itcast.service.impl;import javax.annotation.Resource;import cn.itcast.dao.PersonDao;import cn.itcast.service.PersonService;/** * @author Administrator * Student 业务逻辑类。 * 这个类没有实现到任何的接口,无法使用JDK的Proxy来生成代理对象。 * 改用CGLib来生成代理对象。 */public class StudentServiceBean{/* (non-Javadoc) * @see cn.itcast.service.impl.PersonService#save() */public StudentServiceBean(){System.out.println("构造方法在调用----"+this.hashCode());}public void save(){//对该方法进行拦截,权限控制System.out.println("我是一个业务逻辑方法--save。我所在的类没有实现接口。");}}

由于JDK的Proxy代理需要目标对象实现接口。这里通过CGLib实现动态代理。下面是创建动态代理的工厂类。

package cn.itcast.service.impl;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;/** * @author Administrator * CGLib代理对象工厂 */public class CGLibProxyFactory implements MethodInterceptor{private Object targetObject;//被代理的目标对象public Object createProxyObject(Object targetObject){this.targetObject = targetObject;//通过Enhance继承被代理的目标对象类,绑定回调接口里面的回调方法Enhancer enhancer = new Enhancer();enhancer.setSuperclass(targetObject.getClass());enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object targetObject, Method targetMethod, Object[] args,MethodProxy methodProxy) throws Throwable {// TODO Auto-generated method stubObject result = null;System.out.println("--------before方法执行前-----------");//result = methodProxy.invoke(targetObject, args);--错result = methodProxy.invokeSuper(targetObject, args);//注意是methodProxy委托调用方法System.out.println("--------after方法执行后-----------");//错误写法 targetMethod.invoke/*System.out.println("--------方法执行前-----------");result= targetMethod.invoke(targetObject, args);System.out.println("--------方法执行后-----------");*/return result;}}

JUnit4测试:

package junit.test;import static org.junit.Assert.*;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.itcast.service.PersonService;import cn.itcast.service.impl.CGLibProxyFactory;import cn.itcast.service.impl.JDKProxyFactory;import cn.itcast.service.impl.PersonServiceBean;import cn.itcast.service.impl.StudentServiceBean;public class SpringTest {@Testpublic void cglibProxyTest(){//这里就不同过容器进行创建StudentServiceBean了CGLibProxyFactory cglibf = new CGLibProxyFactory();//因为代理对象实现了目标对象的所有接口,所以也可以生产的代理对象也是可以赋值给PersonSercviceStudentServiceBean studentServiceBeanProxy = (StudentServiceBean) cglibf.createProxyObject(new StudentServiceBean());studentServiceBeanProxy.save();}}

OK .Passed....


CGLib总结就是:

  1. * 根据class对象创建该对象的代理对象 
  2.   * 1、设置父类;2、设置回调 
  3.   * 本质:动态创建了一个class对象的子类 
  4.   *  
  5.   * @param cls 
  6.   * @return 

0 0