我有一个POJO类,其注释方法使用@Transactional
public class Pojo {
@Transactional
public void doInTransaction() {
...
}
}
Spring声明式事务管理基于AOP,但我没有任何经验。我的问题是:
是否有可能在单独调用(new Pojo).doInTransaction()
时,Spring将启动一个事务。
答案 0 :(得分:3)
Spring声明式事务 管理是基于APO,但我没有 对此有任何经验。
我建议您开始使用它,您将获得使用AOP使用交易建议的经验。一个很好的起点是here。
调用时是否可能 (新Pojo).doInTransaction()单独, Spring将启动一个Transaction。
不,你不能指望Spring知道你手动调用的bean。但是,听起来您希望避免声明式事务管理并执行程序化事务管理。使用Transaction Template有一种方法可以使用Spring。那是你在找什么?
答案 1 :(得分:1)
这有点可能,但是以一种繁琐的方式:你必须使用AutowireCapableBeanFactory
机制。
这是一个事务类,例如
public interface FooBar{
void fooIze(Object foo);
}
public class FooBarImpl implements FooBar{
@Transactional
@Override
public void fooIze(final Object foo){
// do stuff here
}
}
以下是我们如何使用它:
public class FooService implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(
final ApplicationContext applicationContext){
this.applicationContext = applicationContext;
}
public void serviceMethod(){
//declare variable as interface, initialize to implementation
FooBar fooBar = new FooBarImpl();
// try to use it, won't work, as it's not a proxy yet
Object target = new Object[0];
fooBar.fooIze(target); // no transaction
// now let spring create the proxy and re-assign the variable
// to the proxy:
fooBar = // this is no longer an instance of FooBarImpl!!!
(FooBar) applicationContext
.getAutowireCapableBeanFactory()
.applyBeanPostProcessorsAfterInitialization(fooBar,
"someBeanName");
fooBar.fooIze(fooBar); // this time it should work
}
}
这不是最佳做法。首先,它使您的应用程序高度了解Spring Framework,并且它违反了依赖注入原则。所以只有在没有别的办法时才使用它!
答案 2 :(得分:1)
是的, 是可能的。 Spring 不要求使用@Transactional
的动态代理才能工作。相反,您可以使用AspectJ提供的“真正的AOP”。
答案 3 :(得分:0)
Spring通过Annotation处理事务的方式正如你所说的那样使用AOP。 AOP位使用动态代理实现(请参阅doc)
所以为了做到这一点你需要通过spring容器检索你的类的实例(这里是Pojo),因为为了使它工作,Spring将返回你的Pojo上的动态代理,它将自动包围任何注释使用事务管理代码的方法。
如果你只是做一个
Pojo p = new Pojo();
p.doInTransaction();
Spring在这里没有任何角色,你的方法调用也不在事务中。
所以你需要做的就是这样
ApplicationContext springContext = ...;
Pojo p = (Pojo) springContext.getBean("your.pojo.id");
p.doInTransaction();
注意:这是一个示例,您应该更喜欢依赖注入,而不是从上下文中手动检索bean
通过这样做,并且通过正确配置的Spring上下文,Spring应该了解您的类以扫描事务注释并自动将bean包装到注释感知动态代理实例中。从你的观点来看,你不会改变任何东西,你仍然会将你的对象转换为你自己的类,但如果你试图打印出你的春天上下文Pojo bean的类名,你会得到一些代理作为$。 ..而不是你原来的班级名称。
无论如何,请查看此链接:link text