java中 jdk 动态代理和CGLIB 动态代理


实例:

public class UserDaoImpl implements UserDao{

    /**
     * 业务逻辑和非业务逻辑混在一起,导致代码不易维护,
     * 解决办法动态代理或者aop
     */
 @Override
  public void addUser() {
     //记录日志
      MyLog.doLog(this.getClass());
      // 业务代码
      System.out.println("添加学生数据");
     //提交事务
      MyTransaction.doTransaction(this.getClass());
 }

在我们的编程过程中,遇到很多中这样的情况,非业务逻辑和业务代码混在一起,并且每个方法都是这样,导致代码的耦合性很强,并且维护性可读性降低。那有没有一种方法可以解决这种问题呢?那就是动态代理,用代理对象来解决这个问题。

JDK动态代理

public class UserDaoImpl implements UserDao{

    /**
     * 业务逻辑
     */
 @Override
  public void addUser() {
      // 业务代码
      System.out.println("添加学生数据");
 
 }
public class MyLog {
    public static void doLog(Class<?> clazz){
        System.out.println("记录日志"+clazz.getName());
    }
}
public class MyTransaction {
    public static void doTransaction(Class<?> clazz){
        System.out.println("提交事务"+clazz.getName());
    }
}
/**
 *jdk 动态代理拦截器
 * 代理类实现InvocationHandler接口
 *
 * @author 李娜
 * @version 0.0.1
 * @since 0.0.1  2019-04-04
 */
public class MyInvocationHandler implements InvocationHandler {

    private Object target;
    /**
     * 通过构造方法将要增强的类对象传入
     */
    public MyInvocationHandler(Object target){
        this.target=target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        //记录日志
        MyLog.doLog(target.getClass());
        //业务处理
        Object invoke=method.invoke(target,args);
        //处理事务
        MyTransaction.doTransaction(target.getClass());
        return invoke;
    }
}

在调用代理对象的addUser方法时,进入到了拦截器的invoke方法体
拦截器中invoke方法体的内容就是代理对象方法体的内容

    /*
     * 测试动态代理
     */
    @Test
    public void testProxy(){
        //创建目标类对象
        UserDaoImpl userDao=new UserDaoImpl();

        //创建代理
        UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new MyInvocationHandler(userDao));

        userDaoProxy.addUser();
    }

打印结果:
在这里插入图片描述

CGLIB 动态代理

package com.cj.study.proxycglib;
 
public interface PersonService {
	
	public String savePerson();
	
	public void updatePerson();
	
	public void deletePerson();
	
}
package com.cj.study.proxycglib;
 
public class PersonServiceImpl implements PersonService{
 
	@Override
	public String savePerson() {
		System.out.println("添加");
		return "保存成功!";
	}
 
	@Override
	public void updatePerson() {
		System.out.println("修改");
	}
 
	@Override
	public void deletePerson() {
		System.out.println("删除");
	}
 
}
package com.cj.study.proxycglib;
 
public class MyTransaction {
	public void beginTransaction(){
		System.out.println("开启事务 ");
	}
	public void commit(){
		System.out.println("提交事务");
	}
}

package com.cj.study.proxycglib;
 
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 PersonServiceInterceptor implements MethodInterceptor{
	//目标类
	private Object target;
	//增强类
	private MyTransaction myTransaction;
	//构造函数注入目标类和增强类
	public PersonServiceInterceptor(Object target,MyTransaction myTransaction){
		this.target = target;
		this.myTransaction = myTransaction;
	}
	
	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 arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		myTransaction.beginTransaction();
		Object returnValue = arg1.invoke(this.target, arg2);
		myTransaction.commit();
		return returnValue;
	}
	
}

package com.cj.study.proxycglib;
 
import org.junit.Test;
 
public class ProxyTest {
	@Test
	public void test(){
		Object target = new PersonServiceImpl();
		MyTransaction myTransaction = new MyTransaction();
		PersonServiceInterceptor interceptor = new PersonServiceInterceptor(target, myTransaction);
		PersonService personService =(PersonService) interceptor.createProxy();
		String returnValue = (String)personService.savePerson();
		System.out.println(returnValue);
	}
}

运行结果:
在这里插入图片描述
通过上面两种代理可以实现目标方法的增强,但是问题是太过于麻烦,我们需要自己去生成代理对象,自己手写拦截器,在拦截器里自己手动的去把要增强的内容和目标方法结合起来,这用起来还是有点繁琐。

那spring Aop就不需要自己手写了,aop会自动创建代理对象,并按照你的配置把增强的内容和目标方法结合起来。spring Aop 的原理下节分享~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗琪小姐姐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值