Java Spring使用new创建的对象启动事务

Java Spring使用new创建的对象启动事务,java,spring,spring-aop,spring-transactions,Java,Spring,Spring Aop,Spring Transactions,我有一个POJO类,其方法用@Transactional public class Pojo { @Transactional public void doInTransaction() { ... } } Spring声明性事务管理基于AOP,但我没有这方面的经验。我的问题是: 是否可能在单独调用(新Pojo).doInTransaction()时,Spring将启动事务。Spring通过注释处理事务的方式是使用AOP,正如您所说的那样。 AOP位使

我有一个POJO类,其方法用
@Transactional

public class Pojo {

    @Transactional
    public void doInTransaction() {
        ...
    }
}
Spring声明性事务管理基于AOP,但我没有这方面的经验。我的问题是:
是否可能在单独调用
(新Pojo).doInTransaction()时,Spring将启动事务。

Spring通过注释处理事务的方式是使用AOP,正如您所说的那样。 AOP位使用动态代理实现(请参阅)

因此,为了做到这一点,您需要通过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包装到注释感知的动态代理实例中。从不会改变任何东西的角度来看,您仍然可以将对象强制转换为您自己的类,但是如果您尝试打印出spring上下文Pojo bean的类名,您将得到代理$。。。而不是你原来的类名

请查看此链接:

Spring声明性事务 管理是基于APO的,但我不是 你有这方面的经验吗

我建议您开始使用它,您将获得使用AOP使用事务建议的经验。一个好的起点是

调用 (新Pojo).doInTransaction()单独, Spring将启动一个事务


不,您不能期望Spring知道您手动调用的bean。但是,听起来您希望避免声明式事务管理,而进行编程式事务管理。有一种方法可以通过使用弹簧来实现这一点。这就是你想要的吗?

这是有可能的,但方式很麻烦:你必须使用这个机制

下面是一个事务类作为示例

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框架,并且违反了依赖项注入原则。因此,只有在没有其他方法的情况下才使用此选项

是的,这是可能的。Spring不需要使用动态代理来工作
@Transactional
。相反,您可以使用AspectJ提供的“真正的AOP”

有关详细信息,请参阅