티스토리 뷰

Programming/Spring

Spring Properties

Albothyl 2020. 5. 2. 13:13

some properties

some.url=https://www.some.com

 

1. @PropertySource

- config class
@PropertySource("classpath:/my/application/some.properties")

or 

@PropertySources({
        @PropertySource("classpath:/my/application/some.properties"),
        @PropertySource(name="otherProperties", value={"classpath:/my/application/other.properties"})
})

or

@PropertySource({"classpath:/my/application/some.properties", "classpath:/my/application/other.properties"})

and

/**
 * PropertySourcesPlaceholderConfigurer는 꼭 static으로 설정한다.
 * PropertySourcesPlaceholderConfigurer는 BeanFactoryPostPostProcessor 후처리기로 되어있다.
 * @Bean을 처리하는 기능도 위와 같은 BeanFactoryPostPostProcessor 후처리기로 되어있다.
 * @Bean 메소드에서 다른 후처리기를 만들어서 다시 @Bean이 있는 class의 bean 설정을 가공하도록 만들 수 없기 때문이다.
 * 그래서 스프링은 bean 후처리기가 만들어지기 전에 static으로 정의된 bean을 먼저 만들어서 이 문제를 해결한다.
 */
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
	PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
	return propertySourcesPlaceholderConfigurer; //@Value filed에 di하기 위한 설정.
}

- usage
@Value("${some.uri}")
private String someUrl;

or 

@Autowired
Environment environment;

environment.getProperty("some.url")

 

2. PropertiesFactoryBean

- config class
@Bean(name = "someProperties")
public PropertiesFactoryBean mapper() {
    PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
    propertiesFactoryBean.setLocation(new ClassPathResource("my/project/some.properties"));
    return propertiesFactoryBean;
}

- usage
@Value("#{someProperties['some.url']}") //SpEL
private String someUrl;

or

@Resource(name = "someProperties")
private Properties someProperties;

someProperties.getProperty("some.url")

 

3. Use SpEL

@Value("#{ systemProperties['user.region'] }")
private String defaultLocale;

@Value("#{ T(java.lang.Math).random() * 100.0 }")
private Integer randomNumber;

 

4. Resource convert

String path = "classpath:my/project/some.properties";
Resource resource = applicationContext.getResource(path);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
PropertiesPropertySource myPropertySource = new PropertiesPropertySource("myPropertySource", properties);

ConfigurableEnvironment environment = (ConfigurableEnvironment) applicationContext.getEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addLast(myPropertySource);

 

5. ConfigurationPropertiesApplicationContextInitializer

1 ~ 4번 까지는 appliationContext이 초기화 과정에서 property를 처리한다. applicationContext 초기화(refresh) 이전에 property 작업이 필요할 경우 ApplicationContextInitializer 구현하여 사용한다.

public class ConfigurationPropertiesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

	@Override
	public void initialize(ConfigurableApplicationContext applicationContext) {
			...
	}
}
* java web application
(web.xml)
<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.java.ConfigurationPropertiesApplicationContextInitializer</param-value>
</context-param>


* -------------------------------
* test
@ContextConfiguration(initializers = ConfigurationPropertiesApplicationContextInitializer.class)


* -------------------------------
* pojo java
// Create context, but dont initialize with configuration by calling 
// the empty constructor. Instead, initialize it with the Context Initializer.
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ConfigurationPropertiesApplicationContextInitializer initializer = new ConfigurationPropertiesApplicationContextInitializer();
 
// ApplicationContextInitializer가 ApplicationContext를 초기화해주는 형태
initializer.initialize( ctx );
 
// @Configuration 클래스를 등록하고 초기화
ctx.register( com.my.classpath.StackOverflowConfiguration.class );
ctx.refresh()

6. Spring resource load flow

1. applicationContext 생성 시점
AnnotationConfigApplicationContext

  AnnotatedBeanDefinitionReader
    constructor
	  getOrCreateEnvironment(registry)
		  AbstractApplicationContext
			  //Environment
			  getEnvironment()
				  StandardEnvironment
					  systemEnvironment
						  AbstractEnvironment
							  System.getProperty(attributeName)
								  getSecurityManager()
							  System.getenv(attributeName)
								  getSecurityManager()

  ClassPathBeanDefinitionScanner
    constructor
	  getOrCreateEnvironment(registry) //BeanDefinitionRegistry is applicationcontext
		  AbstractApplicationContext
			  //Environment
			  getEnvironment()
				  StandardEnvironment
					  systemEnvironment
						  AbstractEnvironment
							  System.getProperty(attributeName)
								  getSecurityManager()
							  System.getenv(attributeName)
								  getSecurityManager()



2. applicationContext 생성 후 refresh
AbstractApplicationContext
	
  prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()))

  beanFactory.registerResolvableDependency(ResourceLoader.class, this)
	DefaultResourceLoader
		getResourceByPath(String path) //application imple override
			ClassPathContextResource
			    createRelative(String relativePath)

 

참고

- https://jjhwqqq.tistory.com/250 (classpath)

- https://jjhwqqq.tistory.com/251 (spel)

- https://kwonnam.pe.kr/wiki/springframework/propertysource (spring property)

'Programming > Spring' 카테고리의 다른 글

@Order 사용시 주의점  (0) 2021.02.08
Spring SpEL (Expression Language)  (0) 2020.05.02
JDBC Template Query Logging  (0) 2019.08.02
RetryTemplate  (0) 2019.07.24
[주의] Controller Parameter Mapping Exception  (0) 2019.07.09
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함