Spring学习心得(13)-- jdk动态代理
2017-03-14 15:07
405 查看
引入:
在前面我们涉及到了静态代理,并且了解了它的缺点之后,我们来谈一下动态代理。
首先动态代理分成以下几种情况:
1、目标类和代理类实现共同的接口 a)、jdk代理(即借助了jdk的API完成)
2、代理类继承了目标类
a)、hibernate:javasist
b)、spring:cglib
注:javasist是一个jar包,在学习hibernate的时候,我们使用了
Person person=session.load(Class clazz,Serializable id);
其中session.load得到的是一个javasist类,这一点在以前hibernate的帖子大家可以看到,这个就是javasist类,继承了Person类,所以它不用强转类型 。同时cglib也是一个包,这个在后面我们会讨论到。
//首先,我们需要创建一个核心类:student public class Student implements Serializable { private Long sid; private String sname; private String sdescription; //省略getter&setter } //接口: public interface StudentDAO { //增加学生 public void saveStudent(Student student); //修改学生 public void updateStudent(Student student,Serializable id); //删除学生 public void deleteStudent(Student student); } //事务类 public class MyTransaction extends hibernateUtils{ private Transaction myTransaction; //开启事务 public void beginTransaction(){ myTransaction=sessionFactory.getCurrentSession().beginTransaction(); } //提交事务 public void commit(){ myTransaction.commit(); } } //帮助类 public class hibernateUtils { static SessionFactory sessionFactory; static{ Configuration configuration=new Configuration(); //按照指定位置及名字读物hibernate的配置文件 configuration.configure("cn/ansel/hibernate/jdkProxy/hibernate.cfg.xml"); //得到sessionFactory sessionFactory=configuration.buildSessionFactory(); } } //目标类 public class StudentDAOImpl extends hibernateUtils implements StudentDAO { //因为下面都要用到session,免去重复些代码 private Session session=sessionFactory.getCurrentSession(); //删除学生 @Override public void deleteStudent(Student student) { session.delete(student); } //保存学生 @Override public void saveStudent(Student student) { session.save(student); } //修改学生 @Override public void updateStudent(Student student, Serializable id) { session.get(student.getClass(), id); session.update(student); } } //拦截器: public class StudentInterceptor implements InvocationHandler { /** * 拦截器的定义: * 1、引入目标类 * 2、引入事务 * 3、利用构造函数把目标类和事务导入 * 4、填充invoke方法, */ private Object target; private MyTransaction myTransaction; public StudentInterceptor(Object target, MyTransaction myTransaction) { this.target = target; this.myTransaction = myTransaction; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在这里考虑到事务,但是在目标类中不考虑事务 myTransaction.beginTransaction(); method.invoke(target, args); myTransaction.commit(); return null; } } //映射文件:Student.hbm.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- 把相应的核心类导入 --> <class name="cn.ansel.hibernate.jdkProxy.Student"> <!-- 给其中的属性赋值 --> <id name="sid" length="11"> <generator class="increment"></generator> </id> <property name="sname" length="11"></property> <property name="sdescription" length="111"></property> </class> </hibernate-mapping>配置文件:hibernate.cfg.xml
需要特别注意的就是我们使用了session.getCurrentSession,所以要在配置文件中添加图中红色部分的属性。
//然后是测试类: public class jdkProxyTest { @Test public void test(){ //获取事务 MyTransaction myTransaction=new MyTransaction(); //得到目标类 Object target=new StudentDAOImpl(); //得到拦截器类,并把事务跟目标类传入 StudentInterceptor interceptor=new StudentInterceptor(target, myTransaction); //**调用代理类的方法,得到代理对象**, //这里需要的三个参数: //第一个是目标类的加载器, //第二个是目标类实现的接口 //第三个是拦截器 StudentDAO dao=(StudentDAO) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor); //新建学生 Student student=new Student(); //使用动态代理对象添加学生 dao.saveStudent(student); } }
运行结果:
1、 代理对象有多少方法,方法的名称是什么?
因为代理对象和目标类一样,同样的实现了接口,所以接口中有多少方法,代理对象中就有多少个方法,名称和接口中的方法的名称一样。
2、 拦截器中的invoke方法在什么时候执行的?
当在客户端,代理对象调用方法的时候,进入到了invoke方法
3、 拦截器中的invoke方法中的method参数在什么时候传递的值?
当在客户端,代理对象调用方法的时候,进入到了invoke方法,这个时候,method参数就是代理对象调用的方法。
4、 代理对象的方法体的内容是什么?
代理对象的方法体的内容就是invoke方法体的内容
代理对象的方法体:
1、 开启事务
2、 目标方法
3、 事务的提交
4、 代理对象的方法体就把事务和目标方法结合在一起了,这样做的目的就是为了让目标类的目标方法和事务的方法松耦合。
流程图
相关文章推荐
- Spring学习心得(14)--cglib动态代理
- spring aop学习8:spring对jdk和cglib动态代理的选择
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring AOP 学习之java JDK动态代理
- Spring学习——jdk动态代理例子
- Spring学习总结——静态代理、JDK与CGLIB动态代理、AOP+IoC
- spring入门(13)---JDK动态代理
- spring源码学习【准备】之jdk动态代理和cglib动态代理的区别和性能
- SSH与SSM学习之Spring13——动态代理之通知的使用
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring学习之动态代理(JDK动态代理和CGLIB动态代理)
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- Spring学习心得(0)--动态代理
- spring源码学习之【准备】jdk动态代理例子
- Spring学习(1)AOP初步—JDK动态代理
- AOP学习心得&jdk动态代理与cglib比较
- spring对AOP的支持 JDK动态代理和CGLIB的区别
- JDK动态代理干了什么事情?为什么我的事务会不起效?spring的事务到底应该怎么使用?原理是什么?
- spring中JDK动态代理
- [Spring学习笔记 4 ] AOP 概念原理以及java动态代理