JDK提供的代理类
用动态代理管理Hibernate的事务处理(模拟)
Person类
public class Person {
private String name;
private long pid;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getPid() {
return pid;
}
public void setPid(long pid) {
this.pid = pid;
}
}
接口类PersonDao.java
定义增删改查方法
public interface PersonDao {
void savePerson();
void updatePerson();
void deletePerson();
List<Person> selectPerson();
}
实现类
接口类的具体实现
public class PersonDaoImpl implements PersonDao{
@Override
public void savePerson() {
System.out.println("save Person!");
}
@Override
public void updatePerson() {
System.out.println("update Person!");
}
@Override
public void deletePerson() {
System.out.println("delete Person!");
}
@Override
public List<Person> selectPerson() {
List<Person> list = new ArrayList<>();
Person p = new Person();
p.setName("name");
p.setPid(90L);
list.add(p);
return list;
}
}
事务处理类(事务的开启和提交)
public class Transaction {
public void beginTransaction(){
System.out.println("=begin transaction...=");
}
public void commit(){
System.out.println("=commit...=");
}
}
拦截器(实际上是代理类)
主要注入目标类和事务处理类
public class PersonInterceptor implements InvocationHandler{
private PersonDao personDao;
private Transaction transaction;
public PersonInterceptor(PersonDao personDao,Transaction transaction){
this.personDao = personDao;
this.transaction = transaction;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj;
String methodName = method.getName();
if("savePerson".equals(methodName)||"updatePerson".equals(methodName)
||"deletePerson".equals(methodName)){
//开启事务
transaction.beginTransaction();
obj = method.invoke(this.personDao, args);
//提交事务
transaction.commit();
}else{
obj = method.invoke(this.personDao, args);
}
return obj;
}
}
测试类
public class PersonTest {
@Test
public void test(){
PersonDao pImpl = new PersonDaoImpl();
Transaction transaction = new Transaction();
PersonInterceptor interceptor = new PersonInterceptor(pImpl, transaction);
/**
* 目标类的类加载器
* 目标类的接口
* 拦截器
*/
PersonDao p = (PersonDao) Proxy.newProxyInstance(PersonDaoImpl.class.getClassLoader(),
PersonDaoImpl.class.getInterfaces(),interceptor);
p.deletePerson();
}
}
cglib动态代理
拦截器PersonInterceptor
- 导入cglib的jar包
- 实现MethodInterceptor接口,实现intercept类
定义createProxy方法,将目标类设置为代理类的父类,拦截器设置为回调函数
public class PersonInterceptor implements MethodInterceptor{ private Object target; private Transaction transaction; public PersonInterceptor(Object object,Transaction transaction){ this.target = object; this.transaction = transaction; } public Object createProxy(){ Enhancer enHancer = new Enhancer(); enHancer.setSuperclass(this.target.getClass()); //设置目标类为代理类的父类 enHancer.setCallback(this); //设置拦截器为回调函数 return enHancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { String methodName = method.getName(); if("savePerson".equals(methodName)||"updatePerson".equals(methodName) ||"deletePerson".equals(methodName)){ //开启事务 transaction.beginTransaction(); obj = method.invoke(this.target, args); //提交事务 transaction.commit(); }else{ obj = method.invoke(this.target, args); } return obj; } }
cglib代理与jdk代理的区别
JDK代理
1. 目标类和代理类都实现目标接口
2. 代理类继承InvocationHandler,实现invoke方法。该方法中是代理对象的方法体
3. 当客户端用代理对象调用方法的时候,invoke方法执行。
cglib代理
1. 目标类是代理类的父类
2. 拦截器必须实现MethodInterceptor,实现interceptor方法。
3. 使用字节码增强机制创建代理对象。(不太懂)