Using Spring IoC to set up enum values

后端 未结 13 1969
名媛妹妹
名媛妹妹 2020-11-30 06:06

Is there a way to set up such enum values via Spring IoC at construction time?

What I would like to do is to inject, at class load time, values that are hard-coded i

13条回答
  •  爱一瞬间的悲伤
    2020-11-30 06:33

    I have faced the same issue when I was working to localize my enum label in different locales.

    Enum Code:

    public enum Type {
       SINGLE("type.single_entry"),
       MULTIPLE("type.multiple_entry"),
       String label;
    
       Type(String label) {
         this.label = label;
       }
    
       public String getLabel() {
         String translatedString = I18NTranslator.getI18NValue(getLocale(), label);
         return StringUtils.isEmpty(translatedString) ? label : translatedString;
       }
    }
    

    My I18NTranslator class which basically load the message source to get localized content. I18Ntransalator class depends on springContext if you don't write you might face a peculiar bug. Some time might face a dependency related which causes null pointer exception. I had put a lot of effort to resolve this issue.

    @Component
    @DependsOn({"springContext"})
    public class I18NTranslator {
    
        private static MessageSource i18nMessageSource;
    
        public static String getI18NValue(Locale locale, String key) {
            if (i18nMessageSource != null)
                return i18nMessageSource.getMessage(key, null, locale);
            return key;
        }
    
        @PostConstruct
        public void initialize() {
            i18nMessageSource = SpringContext.getBean("i18nMessageSource", MessageSource.class);
        }
    }
    

    We have to set the spring context

    @Component
    @Slf4j
    public class SpringContext implements ApplicationContextAware {
    
        private static ApplicationContext context;
    
        public static  T getBean(Class beanClass) {
            return context.getBean(beanClass);
        }
    
        public static  T getBean(String beanClassName, Class beanClass) {
            return context.getBean(beanClassName, beanClass);
        }
    
        @Override
        public void setApplicationContext(ApplicationContext context) throws BeansException {
            SpringContext.context = context;
        }
    }
    

    Now it is time to define the bean for I18NMessageSource.

    @Configuration
    public class LocaleConfiguration implements WebMvcConfigurer {
    
        @Bean(name = "i18nMessageSource")
        public MessageSource getMessageResource() {
            ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
            messageResource.setBasename("classpath:i18n/messages");
            messageResource.setCacheSeconds(3600);
            messageResource.setDefaultEncoding("UTF-8");
            return messageResource;
        }
    
        @Bean(name = "localeResolver")
        public LocaleResolver getLocaleResolver() {
            return new UrlLocaleResolver();
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //UrlLocalInterceptor is custom locale resolver based on header paramter.
            UrlLocaleInterceptor localeInterceptor = new UrlLocaleInterceptor();
            registry.addInterceptor(localeInterceptor);
        }
    }
    

    PS: if you need the custom interceptor code I can share in the comment. Defines all local properties files inside resources/i18n folder with messages prefix like messages_en.properties for english and messages_fr.properties fro french.

提交回复
热议问题