Spring에서 사용한 환경 Bean을 자체 구현으로 대체하고자합니다. 이 나쁜 습관입니까, 그렇지 않다면 어떻게해야합니까? 현재 Environment 인터페이스를 구현하고 기존 환경 Bean을 사용하는 Bean을 만들었지 만 환경 Bean을 필요로하는 모든 구성 코드는 이제 내 사용자 정의 환경 Bean을 사용해야합니다. 스프링 환경 빈을 내 환경 변수로 대체하는 것이 더 깔끔할 것이라고 생각 하겠지만, 환경 설정을 변경할 필요가 없다. 현재이 작업을 수행 할 수있는 유일한 방법은 내 자신의 ApplicationContext를 만들어 환경을 내 자신으로 설정하거나 ApplicationContextAware가 될 환경을 설정하는 것입니다. 이 두 가지 모두 나에게 조금은 호기심이있는 것처럼 보입니다.Spring : Application Context에서 생성 된 Environment Bean을 대체하는 방법
제약 : 나는 Spring3의 최신 버전을 사용하고
- .
- Java 기반 구성을 사용하고 있습니다. XML이 아닙니다
고맙습니다.
편집 : 배경
가 나는 경우에 이렇게 내 생각이 결함이 원하는 내가 왜 설명해야 가정합니다. 나는 비 구조적인 "왜 그렇게하고 싶습니까?"라고 피하기 위해 이것을 피했습니다. 응답.
스프링 환경 빈은 속성 값을 찾을 때 일련의 속성 소스를 사용합니다. 전형적인 스택은 다음과 같습니다 (이에 제한되지 않음) :
- JNDI
- 시스템 등록 정보 (-Dmyprop = foo를 통해 설정)
- 환경 변수
- ...
보안상의 이유로 이러한 속성 중 일부 (예 : 데이터베이스 암호)를 암호화해야합니다. 해결책은 Jasypt를 속성 암호화에 사용하는 것입니다. 그러나 Spring/Jasypt는 새로운 속성 소스를 환경에 삽입하는 수단 만 제공합니다. 그래서 : 잠재적으로 암호화 된 값
- 재산권 파일 ... 그러나
, 이는 작업 그룹이 유지 관리 할 속성 만 단일 파일에 저장하거나 속성을 여러 파일로 분산시킬 수 있다는 점에서 이상적인 것은 아닙니다. t 속성 파일, 환경 변수 등. 또한 속성은 속성 소스와 상관없이 암호화 될 수있는 가능성이 있다고 생각합니다.
그래서 환경에 접근하려고 시도 할 때마다 코드의 속성을 암호 해독해야하거나, 나를 위해이 환경 bean을 만들어야한다고 생각합니다.
건설적인 개의 의견과 다른 정보를 환영합니다.
EDIT : 추가 용액
public class EnvironmentBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private static final String CONFIGURATION_PROPERTY_PBE_ALGORITHM = "PBE_ALGORITHM";
private static final String CONFIGURATION_PROPERTY_PBE_PASSWORD = "PBE_PASSWORD";
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
StandardEnvironment environment = (StandardEnvironment) beanFactory.getBean("environment");
if (environment != null) {
StringEncryptor encryptor = this.getEncryptor(environment);
MutablePropertySources mutablePropertySources = environment.getPropertySources();
for (PropertySource<?> propertySource : mutablePropertySources) {
mutablePropertySources.replace(
propertySource.getName(),
new EncryptablePropertySourcePropertySource(propertySource.getName(), propertySource, encryptor));
}
}
}
private StringEncryptor getEncryptor(Environment environment) {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
String algorithm = environment.getProperty(CONFIGURATION_PROPERTY_PBE_ALGORITHM);
if (algorithm != null) {
encryptor.setAlgorithm(algorithm);
}
String password = environment.getProperty(CONFIGURATION_PROPERTY_PBE_PASSWORD);
if (password != null) {
encryptor.setPassword(password);
}
return encryptor;
}
private class EncryptablePropertySourcePropertySource extends PropertySource<PropertySource<?>> {
private StringEncryptor stringEncryptor;
private TextEncryptor textEncryptor;
public EncryptablePropertySourcePropertySource(final String name, final PropertySource<?> propertySource, final StringEncryptor encryptor) {
super(name, propertySource);
this.stringEncryptor = encryptor;
}
public EncryptablePropertySourcePropertySource(final String name, final PropertySource<?> propertySource, final TextEncryptor encryptor) {
super(name, propertySource);
this.textEncryptor = encryptor;
}
@Override
public Object getProperty(String name) {
Object value = this.source.getProperty(name);
if (value != null && value instanceof String) {
value = this.decode((String) value);
}
return value;
}
private String decode(String encodedValue) {
if (!PropertyValueEncryptionUtils.isEncryptedValue(encodedValue)) {
return encodedValue;
}
if (this.stringEncryptor != null) {
return PropertyValueEncryptionUtils.decrypt(encodedValue, this.stringEncryptor);
}
if (this.textEncryptor != null) {
return PropertyValueEncryptionUtils.decrypt(encodedValue, this.textEncryptor);
}
throw new EncryptionOperationNotPossibleException(
"Neither a string encryptor nor a text encryptor exist "
+ "for this instance of EncryptableProperties. This is usually "
+ "caused by the instance having been serialized and then "
+ "de-serialized in a different classloader or virtual machine, "
+ "which is an unsupported behaviour (as encryptors cannot be "
+ "serialized themselves)");
}
}
}
표준 Spring 항목으로는 수행 할 수없는 자신의 '환경'을 롤업하여 무엇을 달성하려고합니까? – geoand
'AbstractApplicationContext'의'setEnvironment()'메소드가 public이라는 것을 볼 수 있습니다. 그래서, 당신은'ApplicationContextAware'를 구현 한 빈을 가지고 앱 컨텍스트를 획득 할 수 있고 거기에서 당신 자신의 환경을 설정할 수 있습니다. 해보지는 않았지만 이것이 내가 시도 할 첫 번째 일이라고 생각합니다. –
@geoand 내 편집을 참조하십시오. – loesak