【问题标题】:Spring managed non-static factory created beansSpring托管的非静态工厂创建的bean
【发布时间】:2013-01-02 10:36:37
【问题描述】:

我有一些 Spring 托管类(通过 xml 配置),其中一个是 SessionFactory,它被注入到另一个 Spring 托管类中。每当这个类需要一个新的 Session 时,它就会在 SessionFactory 上调用 createSession。

但是,除非我弄错了,否则这意味着 Sessions 本身不是 Spring 管理的,这是有问题的,因为它们有一些 @Transactional 方法,这些方法要求 bean 由 Spring 管理。

我一直在阅读有关 FactoryBeans 的内容,但我不确定如何做到这一点的最佳方法,尤其是我的 createSession 方法需要一个参数,而 FactoryBean.getObject() 没有。

我可以使用getObject,然后手动将参数设置得更高,但如果可能的话,我想在工厂中强制设置。

有人可以帮忙吗?提前致谢。下面是一个简化的示例。

public class SessionFactory {

    public final Session createSession(String username){
        Session session = new SessionImpl(username);
        return session;
    }

}


public class SessionImpl implements Session{

    private String username;

    @Override
    @Transactional
    public void doSomething(){
        // Does something
    }

    public void setUsername(String username){
        this.username = username;
    }

    public String getUsername(){
        return username;
    }

}


public class Service {

    private SessionFactory sessionFactory; // Set by Spring through xml config

    public void doSomethingServicy(){

    }

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


}

【问题讨论】:

    标签: xml spring factory


    【解决方案1】:

    我会说你把 @Transactional 注释放在了错误的地方。

    不是会话应该是事务性的;它应该应用于满足您的用例的基于接口的服务方法。这是典型的 Spring 习语。我建议您关注它。

    【讨论】:

    • 谢谢,但很遗憾,目前这不是一个选项,您能提出解决问题的方法吗?
    • 我已经做到了。这是一种选择。随它去吧。或者不要使用 Spring 事务。
    • 我的问题不关心 @Transactional 是否在正确的位置,而是我是否可以从工厂获得 Spring 管理的 bean。我已经明确表示不能移动注释,因为这个问题涉及遗留代码和我无法更改的限制。
    【解决方案2】:

    我通过在 Spring 中创建工厂 bean 并使用工厂 bean 和工厂方法声明一个原型范围的 Session 对象来解决这个问题,如下所示:

    <bean id="sessionFactory" class="com.SessionFactory" >
            <property name="dependencyA" ref="dependencyA" />
            <property name="dependencyB" ref="dependencyB" />
    </bean>
    
    <bean id=session" class="com.SessionImpl" factory-bean="sessionFactory" factory-method="createSession" scope="prototype" />
    

    然后在需要时在代码中检索一个新实例:

    Session session = (Session) applicationContext.getBean(SpringConstants.SESSION_BEAN_NAME, username);
    

    这里的用户名是Object...方法参数的一部分,它构成了传递给工厂createSession方法的参数

    我很欣赏程序的结构可能会更好,但考虑到代码的限制,它很好地解决了问题。

    【讨论】:

      猜你喜欢
      • 2019-04-03
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      相关资源
      最近更新 更多