8.AOP之CGLIB动态代理

1.简介
基于父类的动态代理技术,动态生成一个要代理的子类,子类重写要代理的类的所有非final修饰的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势织入横切逻辑,对方法进行增强。
在这里插入图片描述

2.生成代理对象
在项目目录“/src/main/java/com/steven/proxy”目录下新建CGLIBProxyFactory类,在类中提供一个创建CGLIB代理对象的方法createCGLIBProxyObject,具体代码如下。

public class CGLIBProxyFactory {
    @Autowired
    private IAccountService accountService;

    @Autowired
    private TransactionManager transactionManager;

    public IAccountService createCGLIBProxyObject() {
        /**
         * 采用CGLIB动态代理技术生成目标类的代理对象
         * class    代理类的字节码对象,借助被代理类获取
         * callback 动作类,当代理对象调用代理对象中原方法时,会执行intercept方法
         */
        IAccountService accountServiceProxy = (IAccountService) Enhancer.create(accountService.getClass(), new MethodInterceptor() {
                    /**
                     * @param o 生成的代理对象
                     * @param method 被代理类方法的引用
                     * @param objects 被代理类方法的入参
                     * @param methodProxy 代理方法
                     */
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        try {
                            //手动开启事务
                            transactionManager.beginTransaction();

                            System.out.println("被代理类对象方法将要被执行");
                            //让被代理对象的原方法执行
                            method.invoke(accountService, objects);
                            System.out.println("被代理类对象方法已经被执行");

                            //手动提交事务
                            transactionManager.commit();
                        } catch (Exception e) {
                            e.printStackTrace();
                            //手动回滚事务
                            transactionManager.rollback();
                        } finally {
                            //手动释放资源
                            transactionManager.release();
                        }
                        return null;
                    }
                }
        );

        return accountServiceProxy;
    }
}

3.修改业务层代码
在转账工程基础上,删除业务层的事务控制代码,具体代码如下。

@Service
public class AccountServiceImpl implements IAccountService {
    @Autowired
    private IAccountDao accountDao;

    public void transfer(String outUser, String inUser, Double money) {
        accountDao.out(outUser, money);

        int i = 1 / 0;

        accountDao.in(inUser, money);
    }
}

4.将CGLIBProxyFactory交给Spring容器管理
在applicationContext.xml文件中添加如下bean标签。

<bean id="cglibProxyFactory" class="com.steven.proxy.CGLIBProxyFactory"/>

5.编写测试类

public class Test {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        CGLIBProxyFactory cglibProxyFactory = (CGLIBProxyFactory) context.getBean("cglibProxyFactory");
        IAccountService accountService = cglibProxyFactory.createCGLIBProxyObject();
        accountService.transfer("steven", "sherry", 100d);
    }
}

程序执行成功,查看数据库数据,steven和sherry的10000元数额未发生变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值