j'ai écrit cet exemple simple:printemps et @transactional, est-ce normal?
//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();
}
}
Et voici mon essai:
TestService s1=context.getBean(TestService.class);
TestService s2=context.getBean(TestService.class);
List<Test> list=s1.useController();
System.out.println(s1.flag+" "+s2.flag);
Maintenant, le comportement étrange (im très nouveau avec ressort):
- Si je déclare
@Transactional
la méthode "useController()", la sortie est: true vrai - Si je me déplace
@Transactional
deTestService
àTestControllerImp
, et je déclare "findAll()" avec@Transactional
, la sortie est: false false.
Pourquoi j'ai ce comportement? Je sais par défaut @Autowired
classes sont singletone, mais pourquoi dans le premier cas, le drapeau reste toujours vrai?
Merci à tous.
Alors @Transactional ne fonctionne que si vous l'utilisez dans une implémentation d'interface? – chzbrgla
Oui, sauf si vous utilisez ' '. Puis CGLIB sera utilisé pour créer des sous-classes dynamiques –
@seanizer: Merci, donc pour chaque classe de service, je dois écrire l'interface et sa mise en œuvre? Puis-je changer le mécanisme @Transactional par défaut? Vous dites travailler sur JDK mais débogage s1 et s2 je vois TestService $$ EnhancerByCGLIB $$ 51486891 donc je pense que cela fonctionne sur CGLIB à la place, n'est pas vrai? – blow