【问题标题】:Injecting a single Spring bean instance into a static variable of a utility class将单个 Spring bean 实例注入实用程序类的静态变量
【发布时间】:2020-07-06 10:04:12
【问题描述】:

我有这个使用 Spring 和 Vaadin 构建的 Web 应用程序,为了方便起见,我想在其中执行此操作:

创建一个封装 Spring 服务的实用程序类,并允许在整个应用程序中使用其静态方法,而不必担心到处注入此服务,如下所示:

String configurationValue = ConfigurationUtil.getString("some.property.key");

如果您使用 Vaadin,您可能会发现这是多么方便,因为整个表示层都是用 Java 编写的,您不能总是将 Spring 服务注入到您的 Vaadin 组件中,因为这些 Vaadin 组件本身并不总是 Spring 组件。

这是我的实用程序类:

public final class ConfigurationUtil {

    // this is the spring service:
    private static ConfigurationService configurationService;

    public static void setConfigurationService(final ConfigurationService configurationService) {
        ConfigurationUtil.configurationService = configurationService;
    }

    public static String getString(final String key) {
        return configurationService.getString(key);
    }
}

这是我的服务:

@Service("configurationService")
public class ConfigurationServiceImpl implements ConfigurationService, BeanFactoryAware {

    private final FrameworkService frameworkService;

    @Autowired
    public ConfigurationServiceImpl(final FrameworkService frameworkService) throws IOException, ConfigurationException {
        
        // this is where I set this service bean to the utility class
        ConfigurationUtil.setConfigurationService(this);

        this.frameworkService = frameworkService;
    }

    public String getString(String key)  {
        // code that retrieves a configuration value from our configuration files
    }

}

我的问题是:我有点担心这会导致访问配置服务的瓶颈,因为多个线程将从多个用户会话中调用它。这会是个问题吗?请解释原因。另外,请随时指出此解决方案的其他问题。

【问题讨论】:

  • 没有。但是你应该这样做可能不会。注入依赖或传递它们,为此/类似使用静态方法通常是一种反模式。
  • @M.Deinum 确实,这有点奇怪。谢谢你的 2 美分。

标签: java spring dependency-injection vaadin static-methods


【解决方案1】:

我建议创建一个像这样实现 ApplicationContextAware 的 bean:

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext ac) {
        context = ac;
    }

    public static String getString(final String key) {
        ConfigurationService configurationService = context.getBean(ConfigurationService.class);
        return configurationService.getString(key);
    }

    public static <T> T bean(Class<T> beanType) {
        return context.getBean(beanType);
    }

}

您可以像示例中一样创建一个方法,以提供对 Spring Bean 的静态访问权限或您请求从 ConfigurationService 获取字符串的方法。

顺便说一句。我在 Vaadin 应用程序中经常使用它,因为我不想让每个组件都成为 Spring Bean。

【讨论】:

  • 感谢您的所有麻烦,但我的问题是:我的解决方案会导致瓶颈吗?或者您是否看到该解决方案的任何其他问题。如果没有问题,我完全没问题。
  • 从框架的角度看不是。这取决于您的配置服务在 getString 中的作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多