Spring同一个类中的方法互相调用,注解失效问题的分析和解决

以Transaction注解为例:

@Service
public class TestService {

    @Autowired
    Dao dao;

    @Transactional
    public void methodOne(Object o) {
        dao.save(o);
    }

    public void methodTwo(Object o) {
        methodOne(o);
    }
}

检查事务是否启动:

设置log leve为debug,可以查看是否有下面这个log,判断是否启动了Transaction:
DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name...

原因:

Spring在扫描bean的时候会扫描方法上是否包含@Transactional注解,如果包含,Spring会为这个bean动态地生成一个子类(即代理类,proxy),代理类是继承原来那个bean的。此时,当这个有注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用方法之前就会启动Transaction。然而,如果这个有注解的方法是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,所以就不会启动Transaction,我们看到的现象就是@Transactional注解无效。

示例:

@Service
class TestService{

    @Transactional
    void methodOne(){
        ...
    }

    void methodTwo(){
        methodOne();
    }
}

//Spring扫描注解后,创建了另外一个代理类,并为有注解的方法插入一个startTransaction()方法:
class proxy$TestService{

    TestService testService = new TestService();

    void methodOne(){
        startTransaction();
        testService.methodOne();
    }

    void methodTwo(){
        //由于methodTwo()没有注解,所以不会启动transaction,而是直接调用TestService的实例的methodTwo()方法
        testService.methodTwo();
    }
}

解决方法:

1.把这两个方法分开到不同的类中。

2.把注解加到类名上面。

转自:https://blog.csdn.net/clementad/article/details/47339519

原文地址:https://www.cnblogs.com/helios-fz/p/10996932.html

时间: 2024-10-06 07:54:10

Spring同一个类中的方法互相调用,注解失效问题的分析和解决的相关文章

Spring @Cacheable注解 && 事务@Transactional 在同一个类中的方法调用不生效

@Cacheable 注解在对象内部调用不会生效 代码示例:ProductServiceImpl.java public List<ProductInfoVO> getProductList(CommonRequest<ProductInfoDTO> reqest) { // @Cacheable失效,不会走缓存的 return this.findProductInfoList(reqest); } @Cacheable(cacheNames = "productInfo

《同一个类中不同方法之间的调用相关问题(省略的类名或者this)》

1 //同一个类中不同方法之间的调用相关问题(省略的类名或者this) 2 class A 3 { 4 public void B() 5 { 6 System.out.println("b方法运行"); 7 } 8 public void C() 9 { 10 B();//下面引用<疯狂Java讲义>中的一段话. 11 /* 12 因为Java里的方法不能独立存在,它必须属于一个类或一个对象, 13 因此方法也不能直接像函数那样被独立执行,执行方法时必须使用 14 类或对

梳理:python—同一个类中的方法调用

为什么突然在此提到这个梳理问题呢? 因为在自己实践综合练习学过的知识时,突然觉得有些知识点的运用总是不成功,于是翻过课本进行回顾,总是觉得是对的,可是当再进一步思考"既然是对的,为什么在程序中总是不成功呢?",后来发现,自己理所当然的理解(忽略了细节知识),导致程序通不过,现在结合同一个类中的不同方法中的变量调用 VS 不同函数中的变量调用. 同一个类中的不同方法中的变量调用: class A(): def a_add_b(self): a=10 b=20 self.s =a+b se

C#同一项目中不同文件或类中的方法进行调用

有两种方法,一是将被调用的类设置成静态类Static,这样就可以直接点出来了,二是将被调用的方法所在类设置成public,这几必须在调用类中先将被调用的类进行实体化,new()出来,再点出来. 一. public class A{ public void a(){}; } public class B{ public void b(){ A aa = new A(); aa.a(); } } 二. static class A{ public void a(){}; } static class

第6章 Java类中的方法

1.如何定义java的方法 什么是方法:方法使用来解决一类问题的代码集合,是一个功能模块在类中定义个方法的方法是: 访问修饰符 返回值类型 方法名(参数列表){ 方法体 } 1.访问修饰符,是限制该方法允许被访问的权限范围,可以是:public,protected,private还可以省略2.返回值,如果有返回值需要在这里说明类型,并用return返回,如果没有返回值,使用void3.方法名,使用标识符命名4.参数列表,传递给方法的参数列表 根据返回值和参数的不同,方法大致上分为一下四类:? 无

spring aop之对象内部方法间的嵌套失效

spring aop之对象内部方法间的嵌套失效 先看一下spring 代理原理: *       spring代理嵌套方法调用不生效 * *       Spring AOP defaults to using standard JDK dynamic proxies for AOP *       proxies. This enables any interface (or set of interfaces) to be *       proxied. * *       Spring

在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法

在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的. 比如,下面代码例子中,有两方法,一个有@Transational注解,一个没有.如果调用了有注解的addPerson()方法,会启动一个Transaction:如果调用updatePersonByPhoneNo(),因为它内部调用了有注解的addPerson(),如果你以为系统也会为它启动一个Transaction,那就错了,实际上是没有的. @Service public cla

同一个包,同一个类中,成员变量与成员方法的调用!

分析范围:/**同一个包,同一个类中: * 注意:eat1与eat2是方法的重载(方法名相同,参数列表不同与返回值类型无关) * 在同一个.java文件中可以写多个类,但是只能有一个public修饰的类 * 同一个类中同类型的(静态与非静态)方法之间可以相互调用,例如eat()与sleep(); * 方法1与方法2之间只能调用方法,方法1无法调用方法2里面的变量(局部变量只在方法体中使用); * 静态函数(main方法)不能直接调用非静态成员属性和成员方法; * 静态函数(main方法)可以通过

jsp中怎么调用java类中的方法

在jsp页面中先要,引入java类 例如: <%@page import="javabean.DbConn"%><!-- 引入包中的"类" --> <!--在用到的地方,直接对类实例化--> <% DbConn  DB=new  DbConn(); %> <!--然后就可以直接调用类中的方法--> <% Connection con=DB.conn(); %> jsp中怎么调用java类中的方法