在持久层DAO层中,对数据库操作有影响的增、删、改都需要开启事物,并在执行完增删改之后要提交事物。但如果每个方法都这样写的话,那么代码变显得冗余,采用动态代理的方式来实现这种需求的话,可以使代码更清晰简洁,并且将事物和数据操作解耦。下面是简单的模拟一下此案例,没有真正的数据库连接和事物,只是简单的模拟。
2 . Transaction.java
3. PersonDaoImpl.java
1.Person.java
package cn.it.spring.proxy.dao;
public class Person {
private Integer pid;
private String pnameString;
//省略set和get方法,还有构造函数
}
2 . Transaction.java
package cn.it.spring.proxy.dao;
/**
* 模拟事物类
* @author Administrator
*
*/
public class Transaction {
/**
* 开启事物
*/
public void beginTransaction(){
System.out.println("beginTransaction");
}
/**
* 提交事物
*/
public void commit(){
System.out.println("commit");
}
}
3. PersonDaoImpl.java
package cn.it.spring.proxy.dao;
import java.util.ArrayList;
import java.util.List;
//此处没有实现PersonDao接口
public class PersonDaoImpl{
public void savePerson() {
System.out.println("savePerson");
}
public void deletePerson() {
System.out.println("deletePerson");
}
public void updatePerson() {
System.out.println("updatePerson");
}
public List<Person> getPersons() {
List<Person> persons = new ArrayList<>();
Person person1 = new Person(1, "person1");
Person person2 = new Person(2, "person2");
persons.add(person1);
persons.add(person2);
return persons;
}
}
4.MyInterceptor.java
package cn.it.spring.proxy.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyInterceptor implements MethodInterceptor{
private Object target;
private Transaction transaction;
public MyInterceptor(Object target, Transaction transaction) {
super();
this.target = target;
this.transaction = transaction;
}
/**
* 产生代理对象
*/
public Object createProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setCallback(this);//回调函数 拦截器
enhancer.setSuperclass(this.target.getClass());//设置代理对象的父类
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
if(method.getName().equals("updatePerson")
||method.getName().equals("savePerson")
||method.getName().endsWith("deletePerson")){
transaction.beginTransaction();
method.invoke(target, arg2);//目标对象的目标方法
transaction.commit();
return null;
}else{
return method.invoke(this.target, arg2);//目标对象的目标方法
}
}
}
5. 测试类PersonDaoTest.java
package cn.it.spring.proxy.cglib;
import org.junit.Test;
public class PersonDaoImplTest {
@Test
public void test(){
PersonDaoImpl target = new PersonDaoImpl();
Transaction transaction = new Transaction();
MyInterceptor interceptor = new MyInterceptor(target, transaction);
PersonDaoImpl proxy = (PersonDaoImpl) interceptor.createProxy();
proxy.savePerson();
System.out.println("=============================");
proxy.deletePerson();
System.out.println("=============================");
proxy.updatePerson();
System.out.println("=============================");
for(Person person : proxy.getPersons()){
System.out.println(person.getPnameString());
}
}
}
6.结果