1

我写了这个简单的例子:

//file TestController.java
public interface TestController {

    public List<Test> findAll();

}

//file TestControllerImp.java
@Controller
public class TestControllerImp implements TestController{

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory=sessionFactory;
    }

    public List<Test> findAll() {
        return sessionFactory.getCurrentSession().createQuery("from Test").list();
    }

}

//file TestService.java
@Service
public class TestService {

    @Autowired
    private TestController controller;

    public boolean flag=true;

    public void setController(TestController controller){
        this.controller=controller;
    }

    @Transactional
    public List<Test> useController(){
        flag=false;
        return controller.findAll();
    }

}

这是我的尝试:

TestService s1=context.getBean(TestService.class);
TestService s2=context.getBean(TestService.class);
List<Test> list=s1.useController();
System.out.println(s1.flag+"  "+s2.flag);

现在奇怪的行为(我对春天很陌生):

  1. 如果我声明@Transactional方法“useController()”,输出为:true true
  2. 如果我@Transactional从移动TestServiceTestControllerImp,并且我用 声明“findAll()” @Transactional,则输出为:false false。

为什么我有这种行为?我知道默认@Autowired类是单音的,但为什么在第一种情况下标志仍然是真的?

谢谢大家。

4

1 回答 1

5

@Transactional 机制默认适用于 JDK 代理,并且仅适用于接口。

所以如果你让TestService成为一个接口并TestServiceImpl成为它的实现,那么上面的代码应该可以工作。

例如,将类声明更改为:

@Service
public class TestServiceImpl implements TestService {

但测试代码必须引用接口,而不是类:

// this code remains unchanged
TestService s1=context.getBean(TestService.class);
TestService s2=context.getBean(TestService.class);

参考:

于 2010-11-10T10:42:32.183 回答