Spring 从入门到精通 (十三) 动态代理详解

关键词:Spring | 动态代理 | 详解

本专栏通过理论和实践相结合,系统学习框架核心思想及简单原理,原创不易,如果觉得文章对你有帮助,点赞收藏支持博主 ✨

在这里插入图片描述

一、MethodBeforeAdvice接口

啥时候用? 额外功能运行在原始方法之前时使用它,实现接口方法 before 就可以了

二、before 方法参数详解

  • @param method 额外功能增加给的那个原始方法
  • @param objects 额外功能所增加给的那个原始方法的方法参数
  • @param o 额外功能所增加给的那个原始对象
  • @throws Throwable
public class Before implements MethodBeforeAdvice {
    /**
     * @param method 额外功能增加给的那个原始方法
     * @param objects 额外功能所增加给的那个原始方法的方法参数
     * @param o 额外功能所增加给的那个原始对象
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
    }
}

三、MethodInterceptor(方法拦截器)

这个接口更加灵活,它可以在原始方法前使用,也可以在原始方法之后使用,或者前后都使用,比如事务……

注意,这个接口重名了,我们这里使用的是 aop 包下的这个接口

在这里插入图片描述

MyInter

自己编写的方法拦截器,实现MethodInterceptor 接口,并实现其中的invoke方法

  • @param methodInvocation 额外功能所增加的那个原始方法

我们通过这个参数,拦截方法,通过proceed方法控制方法执行时机,此时就可以添加前置附加操作,后置附加操作,前后都加附加操作等等,更加灵活

public class MyInter implements MethodInterceptor {
    /**
     * @param methodInvocation 额外功能所增加的那个原始方法
     */
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Object obj = null;
        System.out.println("----开启事务----");
        try {
            // 执行原始方法,同时获取执行后的对象,用作整个方法的返回值
            obj = methodInvocation.proceed();
        } catch (Exception e) {
            // 异常了,回滚事务
            System.out.println("----回滚事务----");
            return null;
        }
        // 没问题,提交事务
        System.out.println("----提交事务----");
        return obj;
    }
}

spring.xml

在工厂中配置我们自定义分拦截器类,并将切面配置为我们刚定义的拦截器类

<bean class="com.liu.proxy.MyInter" id="myInter"/>

<aop:config>
    <aop:pointcut id="pc" expression="execution(* *(..))"/>
    <aop:advisor advice-ref="myInter" pointcut-ref="pc"/>
</aop:config>

UserServiceImpl

我们在注册方法实现中添加一个除0异常,猜想登录方法会正常开启事务,处理业务,提交事务,而注册方法会开启事务,执行业务,遇到除0异常被拦截器捕获并回滚事务,最后结束方法。

public class UserServiceImpl implements UserService{
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl register + DAO");
        System.out.println(1/0);
    }

    @Override
    public boolean login(String name, String pwd1) {
        System.out.println("UserServiceImpl login + DAO");
        return true;
    }
}

运行测试看效果

下面就执行测试类,看看是不是我们先想的那样子呢

@Test
public void t2() {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring.xml");
    UserService userService = (UserService) context.getBean("userService");
    userService.login("123","1232");
    userService.register(new User());
}
----开启事务----
UserServiceImpl login + DAO
----提交事务----
----开启事务----
UserServiceImpl register + DAO
----回滚事务----

很棒,和我们想的一样

四、写在最后

座右铭:不要在乎别人如何看你,要在乎你自己如何看未来,看梦想,看世界…!

一起学习的可以私信博主或添加博主微信哦。

专栏:订阅专栏 ✅
关注:关注博主 🆙

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王子周棋洛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值