public interface PersonDao { public void savePerson();}
public class PersonDaoImpl implements PersonDao{ public void savePerson() { System.out.println("save person"); }}
public class Transaction { public void beginTransaction(){ System.out.println("begin transaction"); } public void commit(){ System.out.println("commit"); }}
public class PersonDaoProxy implements PersonDao{ private PersonDao personDao; private Transaction transaction; public PersonDaoProxy(PersonDao personDao, Transaction transaction) { super(); this.personDao = personDao; this.transaction = transaction; } public void savePerson() { this.transaction.beginTransaction(); this.personDao.savePerson(); this.transaction.commit(); }}
/** * 静态代理模式的缺点 * 1、只要写一个dao的是实现类就会写一个代理类 * 2、如果接口中的方法比较多,那么代理类中的方法就比较多,每个方法都需要开启事务、事务的提交 * 所以没有简化开发,没有做到业务逻辑与事务的松耦合 * @author zd * */public class StaticProxyTest { @Test public void testProxy(){ PersonDao personDao = new PersonDaoImpl(); Transaction transaction = new Transaction(); PersonDaoProxy proxy = new PersonDaoProxy(personDao, transaction); proxy.savePerson(); }}动态代理:
1.jdk动态代理(接口代理)
public interface PersonDao { public void savePerson(); public void updatePerson();}
public class PersonDaoImpl implements PersonDao{ public void savePerson() { System.out.println("save person"); } public void updatePerson() { // TODO Auto-generated method stub System.out.println("update person"); }}
public class Transaction { public void beginTransaction(){ System.out.println("begin transaction"); } public void commit(){ System.out.println("commit"); }}
/** * 1、引入目标类和事务类 * 2、完成invoke * @author zd * */public class MyInterceptor implements InvocationHandler{ private Object target; private Transaction transaction; public MyInterceptor(Object target, Transaction transaction) { super(); this.target = target; this.transaction = transaction; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { this.transaction.beginTransaction(); method.invoke(this.target, args); this.transaction.commit(); return null; }}
/** * 1、产生的代理类与接口是什么关系? * 代理类实现了接口 * 2、代理类的方法体的内容是什么? * 方法体的内容就是拦截器中invoke方法体的内容 * 3、拦截器的作用是什么? * 完成invoke方法体中的内容 * 4、拦截器中的invoke方法的参数method * 客户端调用哪个方法,method就代理哪个方法 * 5、拦截器中的invoke方法是什么? * 是代理类的方法 * @author zd * */public class JDKProxyTest { @Test public void testJDKProxy(){ Object target = new PersonDaoImpl(); Transaction transaction = new Transaction(); MyInterceptor interceptor = new MyInterceptor(target, transaction); //产生代理对象 /** * 第一个参数 * 类加载器 * 第二个参数 * 目标类实现的所有的接口 * 第三个参数 * 拦截器 */ PersonDao personDao = (PersonDao)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor); personDao.updatePerson(); }}
2.cglib动态代理(子类代理)
public class Transaction { public void beginTransaction(){ System.out.println("begin transaction"); } public void commit(){ System.out.println("commit"); }}
public class PersonDaoImpl{ public void savePerson() { System.out.println("save person"); }}
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 PersonDaoInterceptor implements MethodInterceptor{ private Object target; private Transaction transact��ȫ,ƽ��ion; public PersonDaoInterceptor(Object target, Transaction transaction) { super(); this.target = target; this.transaction = transaction; } /** * 用来产生代理对象 */ public Object createProxy(){ Enhancer enhancer = new Enhancer(); enhancer.setCallback(this); //设置代理类的父类 enhancer.setSuperclass(PersonDaoImpl.class); return enhancer.create(); } public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { this.transaction.beginTransaction(); method.invoke(target, arg2); this.transaction.commit(); return null; }}
/** * 使用cglib产生的代理类,其代理类是目标类的子类 * @author zd * */public class PersonDaoTest { @Test public void testPersonDaoProxy(){ Object target = new PersonDaoImpl(); Transaction transaction = new Transaction(); PersonDaoInterceptor interceptor = new PersonDaoInterceptor(target, transaction); PersonDaoImpl daoImpl = (PersonDaoImpl)interceptor.createProxy(); daoImpl.savePerson(); }}