【工程截图】
【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.代理对象的方法体就是把事务和目标方法结合在一起了,这样做的目的就是为了让目标类的目标方法和事务的方法松耦合。