Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 216 Vote(s) - 3.42 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using Spring IoC to set up enum values

#11
OK, it's quite fiddly, but it CAN be done.

It's true that Spring cannot instantiate enums. But that's not a problem - Spring can also use factory methods.

This is the key component:

public class EnumAutowiringBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

private final List<Class<? extends Enum>> enumClasses = new ArrayList<>();

public EnumAutowiringBeanFactoryPostProcessor(Class<? extends Enum>... enumClasses) {
Collections.addAll(this.enumClasses, enumClasses);
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (Class<? extends Enum> enumClass : enumClasses) {
for (Enum enumVal : enumClass.getEnumConstants()) {
BeanDefinition def = new AnnotatedGenericBeanDefinition(enumClass);
def.setBeanClassName(enumClass.getName());
def.setFactoryMethodName("valueOf");
def.getConstructorArgumentValues().addGenericArgumentValue(enumVal.name());
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(enumClass.getName() + "." + enumVal.name(), def);
}
}
}
}

Then the following test class shows that it works:

@Test
public class AutowiringEnumTest {

public void shouldAutowireEnum() {
new AnnotationConfigApplicationContext(MyConig.class);

assertEquals(AutowiredEnum.ONE.myClass.field, "fooBar");
assertEquals(AutowiredEnum.TWO.myClass.field, "fooBar");
assertEquals(AutowiredEnum.THREE.myClass.field, "fooBar");
}

@Configuration
public static class MyConig {

@Bean
public MyClass myObject() {
return new MyClass("fooBar");
}

@Bean
public BeanFactoryPostProcessor postProcessor() {
return new EnumAutowiringBeanFactoryPostProcessor(AutowiredEnum.class);
}
}

public enum AutowiredEnum {
ONE,
TWO,
THREE;

@Resource
private MyClass myClass;

}

public static class MyClass {

private final String field;

public MyClass(String field) {
this.field = field;
}
}

}

Reply

#12
I have done it in the following way:

@Component
public class MessageSourceHelper {
@Inject
public MessageSource injectedMessageSource;

public static MessageSource messageSource;

public static String getMessage(String messageKey, Object[] arguments, Locale locale) {
return messageSource.getMessage(messageKey, arguments, locale);
}

@PostConstruct
public void postConstruct() {
messageSource = injectedMessageSource;
}
}

That way you can easily use it in the enum to get messages in the following way:

MessageSourceHelper.getMessage(key, arguments, locale);
Reply

#13
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 extends Object> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}

public static <T extends Object> T getBean(String beanClassName, Class<T> 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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through