springAOP之动态代理(二)

    xiaoxiao2021-08-29  79

    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. 使用字节码增强机制创建代理对象。(不太懂)

    转载请注明原文地址: https://ju.6miu.com/read-677327.html

    最新回复(0)