2013-05-07 46 views
0

我有一個應用程序,我希望能夠根據屬性文件中的值切換DAO實現。 Spring FactoryBean接口看起來好像很好,因爲我可以通過FactoryBean提供DAO,其中我可以根據屬性值進行切換。Spring FactoryBean用法

this SpringSource的博客文章的最後一段,然而,說起這一點:

其中一個重要的外賣是,它是FactoryBean的,而不是factoried對象本身,那生活在Spring容器和享受生命週期掛鉤和容器服務。返回的實例是瞬態的 - Spring對getObject()返回的內容一無所知,並且不會嘗試執行任何生命週期鉤子或其他任何事情。

我的DAO對象包含Spring註釋@Repository@Transactional。鑑於上述段落,如果我通過FactoryBean返回DAO實現,這些註釋是否會被忽略?如果是這樣,確保Spring正在管理FactoryBean返回的bean的好方法是什麼?

編輯:似乎大多數人都在爲問題提供備用配置解決方案。雖然我願意接受這些建議(並且如果它們是好的,它們會加註),但我的問題實際上與FactoryBean的正確使用有關,我將基於這些問題標記正確的答案。

回答

1

您可以在bean的屬性class財產使用佔位符,所以如果你有一個合理的命名約定,你可以有類似

<bean id="customerDao" class="com.example.dao.${dao.type}.CustomerDao"> 

而不是使用工廠bean。

+0

這並不比改變'spring.xml'本身的class屬性好。我的意思是介紹一個屬性,配置屬性文件和後處理器,讓每個打開xml的人都想知道當前的'$ {dao.type}'是否有效。 – 2013-05-07 21:10:50

+0

@Ravi「我希望能夠根據屬性文件中的值切換DAO實現」 - 即使您使用了工廠bean方法,您仍然需要查看屬性文件以瞭解哪些dao類型是有效的。 – 2013-05-07 21:43:31

+0

不,使用'FactoryBean'你可以做類似''。 (有效的MD5加密) – 2013-05-07 21:59:43

0

像往常一樣使用@Component或XML在Spring上下文中創建DAO實例聲明。假設它們都繼承了一個通用接口,那麼稍後您可以使用List來收集它們。請參閱此鏈接獲取更多信息這種類型的回收機制: http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation

例如,在你的DAOFactory:

@Component 
class MyCarDAOFactory implements ApplicationContextAware,FactoryBean<CarDAO> { 

// Getters and Setters for the ApplicationContextAware interface.. 
ApplicationContext ctx; 
// ... 

    // This will place any class that implements CarDAO from Spring Context. 
    @Inject 
    List<CarDAO> carDaoEntries; 

    // This method returns a CarDAO as classified by its Name property specified in 
    // a property placeholder value (should it have been set in Spring context 
    // via a PropertyPlaceholder) 
    public CarDAO getObject() { 
    final String val = ctx.getEnvironment().getProperty("MY_PROPERTY_KEY"); 
     return CollectionUtils.find(carDaoEntries, new Predicate() { 

     public boolean evaluate(Object object) { 
      return ((CarDAO) object).getName().startsWith(val); 
     } 
    }); 
    } 
} 

現在,有可能是一個更優雅/簡單的解決這類問題,所以如果任何人都可以 請進,然後請做!

1

假設你有這樣的事情:

public interface FooDao { 
    // ... 
} 

@Repository("firstFooDao") 
public class FirstFooDao implements FooDao { 
    //... 
} 

@Repository("secondFooDao") 
public class SecondFooDao implements FooDao { 
    //... 
} 

您可以創建一個配置類返回根據一個佔位符,此時,相應的impelementation(本例中爲foo):

@Configuration 
public class FooDaoConfiguration { 

    @Value("${foo}") 
    private String foo; 

    @Autowired 
    private BeanFactory beanFactory; 

    @Bean 
    @Primary 
    public FooDao fooDao() { 
     return beanFactory.getBean(foo, FooDao.class); 
    } 

} 

然後你可以在屬性文件中切換實現:

#foo=firstFooDao 
foo=secondFooDao 

這樣,您的兩個實現都由spring進行管理 - 它不像您鏈接的文檔中的示例,其中返回的對象是使用非彈簧工廠構建的。在這種情況下,所有的bean都在春天實例化。配置類選擇一個。

相關問題