繁体   English   中英

春季启动:“手动”管理bean作用域,以便在运行时以不同状态动态创建bean。 我们的解决方案有问题吗?

[英]Spring boot: Managing bean scope “manually” for dynamically creating beans at runtime with differing states. Is there a problem with our solution?

因此,我们本质上希望有一个通用的JDBC存储库,该存储库可以在运行时用不同的数据库详细信息实例化。 当前的设置基本上是“获取带有详细信息x,y,z的GenericRepo bean。如果存在具有这些详细信息的bean,请改用该bean并使用已经存在的bean。如果不存在,请创建它。”

这似乎是自定义范围可用于的事情,但是我们的解决方案有内在的“错误”之处,可能会引起问题吗?

这是一个Web应用程序,可能有多个人一次使用GenericRepo。

回购

@Component
public class GenericDatabaseDAO {

JdbcTemplate data;

public GenericDatabaseDAO() {}

public GenericDatabaseDAO(String username, String password, String url, String driver) {
    this.data = new JdbcTemplate(
                    DataSourceBuilder.create()
                    .username(username)
                    .password(password) 
                    .url(url)
                    .driverClassName(driver)
                    .build()
                );
}

public GenericDatabaseTableModel runQuery(String query) {

    return new GenericDatabaseTableModel(data.queryForList(query));
}



@Service
public static class DAOService implements ApplicationContextAware {

    ApplicationContext context;
    AutowireCapableBeanFactory factory;

    HashMap<String,GenericDatabaseDAO> beans = new HashMap<String,GenericDatabaseDAO>();

    public GenericDatabaseDAO getDAO(String username, String password, String url, String driver) {

        GenericDatabaseDAO dao = beans.get(username+'@'+url);

        if(dao == null) {

            dao = new GenericDatabaseDAO(username, password, url, driver);
            factory.autowireBean(dao);
            factory.initializeBean(dao, username+'@'+url);

            beans.put(username+'@'+url, dao);
        }

        return dao;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
        this.factory = context.getAutowireCapableBeanFactory();
    }

}
 }

我们如何使用回购

//service class for running sql statements
@Autowired 
GenericDatabaseDAO.DAOService factory;


public void runSqlOnDB(String username, String password, String url, String driver){
GenericDatabaseDAO gdbdao = factory.getDAO(username,password,url,driver);
gbdao.runQuery("sql here");

 }

您可能需要做的就是查看@Configuration批注,以便创建新的bean。

@Bean批注确保返回的是Spring bean。 最后, @Scope注释告诉Spring每次创建一个新实例。

我没有添加,但是您可以轻松研究的是@Cacheable注释,以避免某个bean的多个实例。 注意:要进行缓存,您需要在Maven或Gradle中添加一些额外的Spring jar。 您还需要@EnableCaching

@Configuration
public DaoFactory {

   @Bean
   @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
   // @Cacheable here !
   public getDao(String name, String password, String url, String driver) {
     return new GenericDatabaseDAO(name, password, url, driver);
   }

}

如果要使用它,请执行以下操作

@Autowired DaoFactory daoFactory;
... 

GenericDatabaseDAO dao = daoFactory.getDao("user", "pwd", "url", "driver");

抱歉,我使用@Autowired因为它使示例更简单:)

最后说明: GenericDatabaseDAO类不需要@Component批注。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM