springAOP之动态代理(二)

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

  1. 导入cglib的jar包
  2. 实现MethodInterceptor接口,实现intercept类
  3. 定义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. 使用字节码增强机制创建代理对象。(不太懂)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值