java - 有没有办法在 spring 中重新加载 Autowiring 实例或替换 Autowiring 行为

标签 java spring autowired

目前我有一个在 @Configuration 中创建的 bean,它从 Web 下载 json 文档并创建一个模型对象。使用这个 bean( Autowiring ),许多其他 bean 在启动时被初始化

我需要一种方法来在 web 中的 json 文档发生变化时重新加载 bean。

最好的方法是什么?

代码:

@Configuration
@ComponentScan(basePackages = "com.wellmanage.prism")
public class PrismConfig {

...
@Bean
public Model model(@Qualifier("prismRestTemplate") RestTemplate restTemplate) {

    LOG.info("model()");
    MetadataReader metadataReader = new MetadataReader();
    String prismFormatJson = null;
    if (!isHasLatestTransformedJson()) {
        prismFormatJson = metadataReader.transformToPrismJson(restTemplate, environment);
        setLastGoodPrismConfiguration(prismFormatJson);
    } else {
        prismFormatJson = getLastGoodPrismConfiguration();
    }
    if (model != null) {
        return model;
    } else {
        return metadataReader.createModelForPrism(prismFormatJson);
    }
}

@Configuration
@ComponentScan(basePackages = "com.wellmanage.prism")
public class PrismDataSourceConfig implements DataSourceConfig {

private final Logger LOG = LoggerFactory.getLogger(PrismDataSourceConfig.class);

@Autowired
private Environment environment;

@Autowired
private Model model;

@Primary
@Bean(name = "itdb_dataSource")
public DataSource getDataSource() {

    LOG.info("getDataSource()");
    return getDataSource("itdb");
}

@Bean(name = "dataSourceMap")
public Map<String, DataSource> getDataSourceMap() {

    LOG.info("getDataSourceMap()");

    Map<String, DataSource> dataSourceMap = Maps.newHashMap();
    getDatabases().forEach((name, database) -> {
        Endpoint endpoint = getEndpoint(name);
        DataSource dataSource = createDataSource(endpoint);
        dataSourceMap.put(name, dataSource);
    });

    return dataSourceMap;
}

@Bean(name = "jdbcTemplateMap")
public Map<String, JdbcTemplate> getJdbcTemplateMap() {

    LOG.info("getDataSource()");

    Map<String, JdbcTemplate> jdbcTemplateMap = Maps.newHashMap();
    getDataSourceMap().forEach((name, datasource) -> {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(datasource);
        jdbcTemplateMap.put(name, jdbcTemplate);
    });

    return jdbcTemplateMap;
}

@Override
public Environment getEnvironment() {

    return environment;
}

@Override
public Model getModel() {

    return model;
}

最佳答案

你的做法是非常错误的。 Autowiring 用于在启动时连接依赖项。 (现在实际上不鼓励这样做,支持构造函数参数注入(inject)。)

您可能需要一个@Service 来从远程服务中检索数据模型。然后,您将此服务注入(inject)到需要它来获取模型的类中。

然后您还可以使用像 EhCache 这样的缓存,并向您的方法添加注释 @Cacheable,这样您就不会在每次其他类需要模型时都从远程源获取模型。 (您可以配置您的 ehcache.xml,以决定您希望缓存在刷新数据之前保留多长时间)。

@Service
public class ModelService {

  private final RestTemplate restTemplate;

  public ModelService(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
  }

  @Cacheable(value = "model", key = "#root.methodName")
  public Model getModel() {

    MetadataReader metadataReader = new MetadataReader();
    String prismFormatJson = null;
    if (!isHasLatestTransformedJson()) {
        prismFormatJson = metadataReader.transformToPrismJson(restTemplate, environment);
        setLastGoodPrismConfiguration(prismFormatJson);
    } else {
        prismFormatJson = getLastGoodPrismConfiguration();
    }
    if (model != null) {
        return model;
    } else {
        return metadataReader.createModelForPrism(prismFormatJson);
    }
  }

  //... the rest of the code
}

这里我们配置缓存在 10 分钟后过期:

<config
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns='http://www.ehcache.org/v3'
  xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
  xsi:schemaLocation="
  http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
  http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">

  <service>
    <jsr107:defaults>
      <jsr107:cache name="model" template="model-cache"/>
    </jsr107:defaults>
  </service>

  <cache-template name="model-cache">
    <expiry>
      <ttl unit="minutes">10</ttl>
    </expiry>
  </cache-template>
</config>

关于java - 有没有办法在 spring 中重新加载 Autowiring 实例或替换 Autowiring 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56181130/

相关文章:

java - Undertow Websocket Bean 注入(inject) CDI 问题

java - 使用 Spark 进行字符串转换

Spring Webapp 错误 404 Tomcat 没有获取欢迎文件

spring - 从 Spring Autowiring 中排除子包?

java - 使用 @Component 默认 Autowiring

java - C服务器和Java客户端之间的UDP连接

java - Spring 依赖注入(inject)与写入接口(interface)

java - 为什么 @Autowired 在我的 Controller 中工作但在我的服务中不起作用?

java - 将 Hibernate 集成到在嵌入式 Jetty 上运行的 Spring

java - 将 Spring 配置从 XML 转换为基于 Java : No Qualifying bean Exception