Rom*_*man 82 java spring annotations coding-style
代码中标题的问题:
@Transactional (readonly = true)
public interface FooService {
void doSmth ();
}
public class FooServiceImpl implements FooService {
...
}
Run Code Online (Sandbox Code Playgroud)
VS
public interface FooService {
void doSmth ();
}
@Transactional (readonly = true)
public class FooServiceImpl implements FooService {
...
}
Run Code Online (Sandbox Code Playgroud)
Rom*_*eau 112
来自http://static.springsource.org/spring/docs/2.0.x/reference/transaction.html
Spring团队的建议是,您只使用注释注释具体类
@Transactional,而不是注释接口.您当然可以将@Transactional注释放在接口(或接口方法)上,但这只会在您使用基于接口的代理时按预期工作.注释不是继承的这一事实意味着如果您使用基于类的代理,那么基于类的代理基础结构将无法识别事务设置,并且该对象将不会被包装在事务代理中(这将是非常糟糕的) .因此,请参考Spring团队的建议,并仅使用注释来注释具体类(以及具体类的方法)@Transactional.注意:由于此机制基于代理,因此只会拦截通过代理进入的"外部"方法调用.这意味着'自调用',即目标对象中调用目标对象的其他方法的方法,即使被调用的方法被标记,也不会在运行时导致实际的事务
@Transactional!
(重点加在第一句,其他重点来自原文.)
您可以将它们放在界面上,但要警告在某些情况下交易可能不会发生.请参阅Spring文档的Secion 10.5.6中的第二个提示:
Spring建议您只使用@Transactional注释来注释具体类(以及具体类的方法),而不是注释接口.您当然可以将@Transactional注释放在接口(或接口方法)上,但这只能在您使用基于接口的代理时按预期工作.Java注释不是从接口继承的事实意味着如果您使用基于类的代理(proxy-target-class ="true")或基于编织的方面(mode ="aspectj"),那么事务设置是代理和编织基础设施无法识别,并且该对象不会被包装在事务代理中,这将是非常糟糕的.
出于这个原因,我建议将它们放在实现上.
另外,对我来说,事务似乎是一个实现细节,因此它们应该在实现类中.想象一下,拥有不需要事务性的日志记录或测试实现(模拟)的包装器实现.
Spring的建议是注释具体实现而不是接口.在界面上使用注释并不正确,只能滥用该功能并无意中绕过@Transaction声明.
如果你在一个接口中标记了一些事务性的东西,然后在spring的其他地方引用它的一个实现类,那么spring创建的对象不会明显地遵循@Transactional注释.
在实践中,它看起来像这样:
public class MyClass implements MyInterface {
private int x;
public void doSomethingNonTx() {}
@Transactional
public void toSomethingTx() {}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27956 次 |
| 最近记录: |