1 packageorg.springframework.boot.autoconfigure.context;2
3 importjava.time.Duration;4
5 importorg.springframework.boot.autoconfigure.AutoConfigureOrder;6 importorg.springframework.boot.autoconfigure.EnableAutoConfiguration;7 importorg.springframework.boot.autoconfigure.condition.ConditionMessage;8 importorg.springframework.boot.autoconfigure.condition.ConditionOutcome;9 importorg.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;10 importorg.springframework.boot.autoconfigure.condition.SearchStrategy;11 importorg.springframework.boot.autoconfigure.condition.SpringBootCondition;12 importorg.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration.ResourceBundleCondition;13 importorg.springframework.boot.context.properties.ConfigurationProperties;14 importorg.springframework.boot.context.properties.EnableConfigurationProperties;15 importorg.springframework.context.MessageSource;16 importorg.springframework.context.annotation.Bean;17 importorg.springframework.context.annotation.ConditionContext;18 importorg.springframework.context.annotation.Conditional;19 importorg.springframework.context.annotation.Configuration;20 importorg.springframework.context.support.ResourceBundleMessageSource;21 importorg.springframework.core.Ordered;22 importorg.springframework.core.io.Resource;23 importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;24 importorg.springframework.core.type.AnnotatedTypeMetadata;25 importorg.springframework.util.ConcurrentReferenceHashMap;26 importorg.springframework.util.StringUtils;27
28 /**
29 * {@linkEnableAutoConfiguration Auto-configuration} for {@linkMessageSource}.30 *31 *@authorDave Syer32 *@authorPhillip Webb33 *@authorEddú Meléndez34 */
35 @Configuration36 @ConditionalOnMissingBean(value = MessageSource.class, search =SearchStrategy.CURRENT)37 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)38 @Conditional(ResourceBundleCondition.class)39 @EnableConfigurationProperties40 public classMessageSourceAutoConfiguration {41
42 private static final Resource[] NO_RESOURCES ={};43
44 @Bean45 @ConfigurationProperties(prefix = "spring.messages")46 publicMessageSourceProperties messageSourceProperties() {47 return newMessageSourceProperties();48 }49
50 @Bean51 publicMessageSource messageSource(MessageSourceProperties properties) {52 ResourceBundleMessageSource messageSource = newResourceBundleMessageSource();53 if(StringUtils.hasText(properties.getBasename())) {54 messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(55 StringUtils.trimAllWhitespace(properties.getBasename())));56 }57 if (properties.getEncoding() != null) {58 messageSource.setDefaultEncoding(properties.getEncoding().name());59 }60 messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());61 Duration cacheDuration =properties.getCacheDuration();62 if (cacheDuration != null) {63 messageSource.setCacheMillis(cacheDuration.toMillis());64 }65 messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());66 messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());67 returnmessageSource;68 }69
70 protected static class ResourceBundleCondition extendsSpringBootCondition {71
72 private static ConcurrentReferenceHashMap cache = new ConcurrentReferenceHashMap<>();73
74 @Override75 publicConditionOutcome getMatchOutcome(ConditionContext context,76 AnnotatedTypeMetadata metadata) {77 String basename =context.getEnvironment()78 .getProperty("spring.messages.basename", "messages");79 ConditionOutcome outcome =cache.get(basename);80 if (outcome == null) {81 outcome =getMatchOutcomeForBasename(context, basename);82 cache.put(basename, outcome);83 }84 returnoutcome;85 }86
87 privateConditionOutcome getMatchOutcomeForBasename(ConditionContext context,88 String basename) {89 ConditionMessage.Builder message =ConditionMessage90 .forCondition("ResourceBundle");91 for(String name : StringUtils.commaDelimitedListToStringArray(92 StringUtils.trimAllWhitespace(basename))) {93 for(Resource resource : getResources(context.getClassLoader(), name)) {94 if(resource.exists()) {95 returnConditionOutcome96 .match(message.found("bundle").items(resource));97 }98 }99 }100 returnConditionOutcome.noMatch(101 message.didNotFind("bundle with basename " +basename).atAll());102 }103
104 privateResource[] getResources(ClassLoader classLoader, String name) {105 String target = name.replace('.', '/');106 try{107 return newPathMatchingResourcePatternResolver(classLoader)108 .getResources("classpath*:" + target + ".properties");109 }110 catch(Exception ex) {111 returnNO_RESOURCES;112 }113 }114
115 }116
117 }