关键词: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
----回滚事务----
很棒,和我们想的一样
四、写在最后
座右铭:不要在乎别人如何看你,要在乎你自己如何看未来,看梦想,看世界…!
一起学习的可以私信博主或添加博主微信哦。