【工程截图】
【PersonDao.java】
package com.HigginCui.daoProxy; //目标类接口 public interface PersonDao { public void savePerson(); }
【PersonDaoImpl.java】
package com.HigginCui.daoProxy; //目标类 public class PersonDaoImpl implements PersonDao{ @Override public void savePerson() { System.out.println("save Person..."); } }
【Transaction.java】
package com.HigginCui.daoProxy; public class Transaction { public void beginTransaction(){ System.out.println("begin transaction..."); } public void commit(){ System.out.println("begin commit..."); } }
【personDaoInterceptor.java】
package com.HigginCui.daoProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; //拦截器 public class PersonDaoInterceptor implements InvocationHandler{ private Object target; private Transaction transaction; //构造函数 public PersonDaoInterceptor(Object target,Transaction transaction){ this.target=target; this.transaction=transaction; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //1.开启事务 this.transaction.beginTransaction(); //2.进行savePerson操作 method.invoke(target, args); //目标方法调用方法 //3.提交事务 this.transaction.commit(); return null; } }
【testPerson.java】
package com.HigginCui.test; import java.lang.reflect.Proxy; import org.junit.Test; import com.HigginCui.daoProxy.PersonDao; import com.HigginCui.daoProxy.PersonDaoImpl; import com.HigginCui.daoProxy.PersonDaoInterceptor; import com.HigginCui.daoProxy.Transaction; public class testPerson { @Test public void test(){ Object target=new PersonDaoImpl(); Transaction transaction=new Transaction(); //创建一个拦截器 PersonDaoInterceptor interceptor=new PersonDaoInterceptor(target,transaction); /* * Proxy.newProxyInstance(loader, interfaces, h)方法 * 参数1:loader,目标类的类加载器 * 参数2:interfaces,目标类实现的所有的接口 * 参数3:h,拦截器,即上面创建的拦截器 */ PersonDao personDao=(PersonDao) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor); personDao.savePerson(); } }
【运行结果】
begin transaction...
save Person...
begin commit...
【拦截器中的invoke方法什么时候执行?】
答:当在客户端的代理对象调用方法的时候,进入到了invoke方法。
【拦截器中的invoke方法中的method参数什么时候传递的值?】
答:当在客户端的代理对象调用方法的时候,进入到了invoke方法,这个时候,method参数就是代理对象调用的方法。
【代理对象的方法体的内容是什么?】
答:代理对象的方法体的内容就是invoke方法体的内容。
代理对象的方法体:
1.开启事务
2.目标方法
3.事务的提交
4.代理对象的方法体就是把事务和目标方法结合在一起了,这样做的目的就是为了让目标类的目标方法和事务的方法松耦合。