动态代理的两种实现方式

动态代理的两种实现方式

动态代理
基于JDK版实现
1. 基于jdk版本实现的动态代理
	要求目标类和代理类共同实现一个接口
	基本的实现如下:

目标类:

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Override
    public void transfer(String sourceAccountName, String targetAccountName, Float amount) {

        //查询
        Account sourceAccount = accountDao.findByName(sourceAccountName);
        Account targetAccount = accountDao.findByName(targetAccountName);

        //更改
        sourceAccount.setBalance(sourceAccount.getBalance() - amount);
        targetAccount.setBalance(targetAccount.getBalance() + amount);

        //更新
        accountDao.update(sourceAccount);
        int i = 1 / 0;
        accountDao.update(targetAccount);
    }

}

产生的代理对象:基于接口

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountServiceTest {

    @Autowired
    private AccountService accountService;
    @Autowired
    private TxManager txManager;
    @Test
    public void testTransfer() {
        //代理逻辑
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object obj = null;
                try {
                    //关闭自动提交
                    txManager.begin();
                    obj = method.invoke(accountService, args);
                    //手动提交
                    txManager.commit();
                } catch (Exception e) {
                    //事务回滚
                    txManager.rollback();
                } finally {
                    //事务关闭
                    txManager.close();
                }
                return obj;
            }
        };
        //产生代理对象
        AccountService instance = (AccountService) Proxy.newProxyInstance(
                accountService.getClass().getClassLoader(),
                accountService.getClass().getInterfaces(),
                invocationHandler
        );
        //转账
        instance.transfer("B01", "B02", 1f);
    }
}
基于Cglib实现的
# 使用Cglib实现的动态代理
	当目标对象没有实现的接口的时候 只能使用Cglib来实现动态代理

目标对象: 没有实现的接口的时候

@Service
public class AccountServiceImpl {
	
    @Autowired
    private AccountDao accountDao;

    public void transfer(String sourceAccountName, String targetAccountName, Float amount) {

        //查询
        Account sourceAccount = accountDao.findByName(sourceAccountName);
        Account targetAccount = accountDao.findByName(targetAccountName);

        //更改
        sourceAccount.setBalance(sourceAccount.getBalance() - amount);
        targetAccount.setBalance(targetAccount.getBalance() + amount);

        //更新
        accountDao.update(sourceAccount);
        int i = 1 / 0;
        accountDao.update(targetAccount);

    }

    public void desc(){
        System.out.println("Hello");
    }

}

代理对象:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountServiceTest {

    @Autowired
    private AccountServiceImpl accountService;

    @Autowired
    private TxManager txManager;

    @Test
    public void testTransfer() {

        //代理逻辑
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object obj = null;
                try {
                    //关闭自动提交
                    txManager.begin();
                    obj = method.invoke(accountService, args);
                    //手动提交
                    txManager.commit();
                } catch (Exception e) {
                    //事务回滚
                    txManager.rollback();
                } finally {
                    //事务关闭
                    txManager.close();
                }
                return obj;
            }
        };

        //创建一个增强器
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(AccountServiceImpl.class);
        //设置代理逻辑
        enhancer.setCallback(invocationHandler);
        //产生代理对象
        AccountServiceImpl instance = (AccountServiceImpl) enhancer.create();
        //转账
        instance.transfer("B01", "B02", 1f);
    }
}

总结:

# 当目标对象有实现的接口的时候,我们选择的是使用jdk版本的动态代理
		因为效率高,基于接口来实现的动态代理

# 当目标对象没有实现的接口的时候 ,我们只能使用Cglib来实现动态代理
		基于继承来实现的动态代理

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值