Spring boot:管理 Bean 作用域"manually",用于在运行时动态创建具有不同状态的 bean。我们的解决方案有问题吗?



因此,我们基本上想要拥有一个通用的JDBC存储库,可以在运行时与不同的数据库详细信息进行实例化。当前,该设置本质上是"获取带有详细信息x,y,z的通用bean。P>

这似乎是可以使用自定义范围的东西,但是我们的解决方案可能会固有地"错误"?

这是一个网络应用程序,可能会立即使用多个人使用genericrepo。

repo

@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();
    }
}
 }

我们如何使用repo

//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注释确保返回的是弹簧豆。最后,@Scope注释告诉Spring每次创建一个新实例。

我没有添加的内容,但是您可以轻松调查的是@Cacheable注释,以避免使用某个bean的多个实例。注意:对于缓存,您需要在小毛衣或gradle中进行一些额外的弹簧罐。您还需要@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,因为它使示例变得更加简单:(

最终注意:您不需要@Component GenericDatabaseDAO class。

最新更新