2013-01-02 23 views
1

我有一些Spring托管类(通过xml配置),其中一个是SessionFactory,它被注入另一个Spring托管类。每当这个类需要一个新的Session时,它就调用SessionFactory上的createSession。Spring管理的非静态工厂创建的bean

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

我一直在读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; 
    } 


} 

回答

1

我解决它在春天创建工厂bean,并declaraing一个工厂bean和工厂方法prototype作用域的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方法

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

1

我会说你在错误的地方有@Transactional注解。

这不是会话,应该是事务性的;它应该应用于满足您的用例的基于接口的服务方法。这是典型的春季成语。我建议遵循它。

+0

谢谢,但不幸的是,目前这不是一个选项,你能提出一个解决问题的办法吗? – TheBloodGuy

+0

我已经做了。这是一个选项。去吧。或者不要使用Spring事务。 – duffymo

+0

我的问题并不涉及@Transactional是否在正确的位置,但我是否可以从工厂获得Spring管理的bean。我已经明确指出,移动注释不是一种选择,因为这个问题涉及遗留代码和限制,我无法改变它。 – TheBloodGuy