一、
切面问题:
在开发中会遇到,当在Service中定义了一个方法并且切入之后,从Controller里面调用该方法可以实现切入,但是当在同一个Service中实现另一方法并调用改方法时却无法切入
例如同一个类中方法A,调用它的方法B,这时B方法是无法切入的。
事务问题:
同一个类中方法A没有事务,调用它的方法B,B有事务。这是事务失效。
其实原因很简单,Spring在扫描Bean的时候会自动为标注了@Transactional注解的类生成一个代理类(proxy),当有注解的方法被调用的时候,实际上是代理类调用的,代理类在调用之前会开启事务,执行事务的操作,但是同类中的方法互相调用,相当于this.B(),此时的B方法并非是代理类调用,而是直接通过原有的Bean直接调用,所以注解会失效。
切面也是同理。都是通过代理类执行的。 所有解决此问题就是通过获取代理类去调用方法B
二、这里有两种解决方案,建议使用方案二。
方案一:
通过AopContext.currentProxy()获取代理类,使用它时需要在启动类上设置@EnableAspectJAutoProxy(exposeProxy=true)注解,并exposeProxy设置为true
public void saveUser(User user) {
//获取代理类
UserServiceImpl userService = (UserServiceImpl) AopContext.currentProxy();
userService.test(user);
}
@Transactional
public User test(User user) {
User user1 = userRespository.save(user);
int i = 1/0;
return user1;
}
方案二:
从spring容器中获取bean,通过bean调用。
public void saveUser(User user) {
//获取bean
UserServiceImpl bean = applicationContext.getBean(UserServiceImpl.class);
bean.test(user);
}
@Transactional
public User test(User user) {
User user1 = userRespository.save(user);
int i = 1/0;
return user1;
}