【问题标题】:How to avoid getting bean programmatically for Enums?如何避免以编程方式为 Enums 获取 bean?
【发布时间】:2015-01-31 19:12:48
【问题描述】:

我有Enum

public enum EmployeeErrorCode {
    DELETE_SUCCESS,

    //... Other enumerators

    @Override
    public String toString(){
        ApplicationContext ctx = ContextLoader
                                         .getCurrentWebApplicationContext();
        MessageSource messageSource = (MessageSource) ctx
                                         .getBean("messageSource"); //How to avoid this?
        switch (this) {
        case DELETE_SUCCESS:
            return messageSource.getMessage("deleteEmployee.success", 
                                          null, LocaleContextHolder.getLocale());

        //... Other cases

        default:
            return null;
        }
    }
}

toString 网络中,我为任何Enumerator 指定了消息,但我使用getBean 方法以编程方式获取适当的bean。我怎样才能避免这种情况?

我尝试通过

注入 bean
@Autowired
MessageSource messageSource;

但它没有用。事实上,messageSource 只是null。有没有办法正确地做到这一点?

【问题讨论】:

  • 只需实现MessageSourceResolvable,这将使您的枚举可以传递给MessageSource。这样,任何获得枚举的东西都可以简单地做messageSource.getMessage(enumValue, LocaleContextHolder.getLocale()),或者如果你在 JSP 中使用它,你可以将枚举传递给消息标签,它会处理所有事情。在toString 中这样做是一个非常糟糕的主意(MessageSourceResolvable 稍微不那么糟糕)恕我直言枚举应该很小并且包含尽可能少的逻辑,您已经以任何一种方式将整个域绑定到 Spring。
  • @M.Deinum 有趣的注释,谢谢。我意识到为什么在 toString 中这样做不好。为什么你认为实现MessageSourceResolvable 是个坏主意?
  • 稍微好一点,但如前所述,这取决于您是否愿意拥有自己的域依赖于框架(在这种情况下为 spring)。

标签: java spring


【解决方案1】:

如果MessageSource 是一个打开properties 文件的bean,那么例如如果你的属性文件被称为Messages.properties,那么你可以使用

ResourceBundle bundle = ResourceBundle.getBundle("Messages", LocaleContextHolder.getLocale());
String message = bundle.getString("deleteEmployee.success");

编辑:另一种可能的方法是将MessageSource 注入您的枚举(来自我在Java Generics and Enum, loss of template parameters 的解决方案的想法),如下所示:

public enum EmployeeErrorCode {
    DELETE_SUCCESS {
        @Override
        public String toString() {
             return messageSource.getMessage("deleteEmployee.success", null, LocaleContextHolder.getLocale());
        }
    },
    //... Other enumerators

    private MessageSource messageSource;

    static class EnumInitializer {
        @Autowired
        private MessageSource messageSource;

        @PostConstruct
        public void init() {
            for(EmployeeErrorCode errorCode : EmployeeErrorCode.values() {
                errorCode.messageSource = getMessageSource();
            }
        }

        public MessageSource getMessageSource() {
            return messageSource;
        }
    }
}

但我觉得另一个更干净一些。

【讨论】:

  • 添加了替代答案。
猜你喜欢
  • 1970-01-01
  • 2017-10-23
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
相关资源
最近更新 更多