[SPRING] 싱글 톤을 Spring 빈으로 만드는 올바른 방법
SPRING싱글 톤을 Spring 빈으로 만드는 올바른 방법
싱글 톤을 스프링 빈으로 변환하기 때문에 싱글 톤이 초기화되지 않으면 전체 웹 응용 프로그램의 스프링 컨텍스트가 제대로로드되지 않습니다.
Spring 컨텍스트가 제대로로드되지 않는 장점은 사람들이 배포 중에 구성에주의를 기울이고 수정한다는 것입니다. '비 스프링 빈 (non-spring bean)'싱글 톤을 사용하는 것과는 대조적으로, 초기화 중에 예외가 발생하면 실제 사용자가 누락 된 기능을 엿볼 때까지 아무도 알지 못합니다.
내 변경 사항은 예상대로 작동하지만 .. 올바른 일을하고 있는지 확실하지 않습니다. 이견있는 사람?
코드는 다음과 같습니다.
public class MySingleton {
private static MySingleton INSTANCE = null;
private MySingleton(){}
public static MySingleton getInstance(){
if(INSTANCE == null){
synchronized(MySingleton.class){
if(INSTANCE == null){
try{
doWork()
}catch(Exception e){
throw new IllegalStateException("xyz", e);
}
INSTANCE = new MySingleton();
}
}
}
return INSTANCE;
}
private static void doWork() {
// do some work
}
}
그리고 spring config xml에서 bean은 다음과 같이 정의됩니다.
<bean id="MySingletonBean"
class="com.MySingleton"
factory-method="getInstance" lazy-init="false" singleton="true">
</bean>
노트 : 이것의 대부분은이 기사에서 논의 된 전략과 유사합니다. http://springtips.blogspot.com/2007/06/configuration-hell-remedy-with.html
편집 1 :
이 싱글 톤을 사용하는 클래스는 스프링 빈 (bean) 자체가 아닙니다. 그들은 스프링이 아닌 pojos이므로 봄으로 변환 할 수 없습니다. 그들은 getInstance () 메서드를 사용하여 Singleton을 유지해야합니다.
편집 2 : (아래 설명 된 설명을이 설명 섹션에 복사) 두 가지를 타겟팅하려고합니다.
EDIT 3 (최종) : 나는이 클래스를 싱글 톤으로 만들기로 결심했다. 봄 콩으로 만들지 않을 것이다. 초기화에 실패하면 로그 파일에 무언가를 기록 할 것입니다. 배포를하는 사람이주의를 기울여야합니다 .... 앞으로 언급 할 접근 방법을 포기했습니다. 앞으로 유지 보수의 악몽이 생길 것이라고 생각합니다. 사이에서 선택 - 싱글 톤 또는 봄 콩. 나는 싱글 톤을 선택했다.
해결법
-
==============================
1.INSTANCE 필드를 double-checked locking이 제대로 작동하려면 volatile로 선언해야합니다.
INSTANCE 필드를 double-checked locking이 제대로 작동하려면 volatile로 선언해야합니다.
Effective Java, Item 71을 참조하십시오.
-
==============================
2.왜 첫 번째 장소에서 싱글 톤 패턴을 사용하고 있습니까? Spring이 당신을 위해 bean을 만들고 (디폴트 싱글 톤 스코프로), 그것을 사용하도록하십시오. 물론 항상 누군가가 손으로 콩을 만들지 만, 이것은 제 경우에는 결코 문제가되지 않았습니다.
왜 첫 번째 장소에서 싱글 톤 패턴을 사용하고 있습니까? Spring이 당신을 위해 bean을 만들고 (디폴트 싱글 톤 스코프로), 그것을 사용하도록하십시오. 물론 항상 누군가가 손으로 콩을 만들지 만, 이것은 제 경우에는 결코 문제가되지 않았습니다.
의존성 주입과 스프링 관리 빈 수명주기는 삶을 상당히 쉽게 해줄 것입니다 (피할 수있는 함정이 얼마나 있는지보십시오). 또한 c-tor 또는 @PostContruct 메서드에서 throw 된 예외가 전파되어 응용 프로그램 컨텍스트 시작이 실패하게됩니다.
업데이트 : 나는 당신의 요점을 얻는다. 이것이 내 마음에 들어온 것입니다.
@Service public class Singleton { private static AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>(); public Singleton() { final Singleton previous = INSTANCE.getAndSet(this); if(previous != null) throw new IllegalStateException("Second singleton " + this + " created after " + previous); } public static Singleton getInstance() { return INSTANCE.get(); } }
그리고 Spring이 그 일을하도록하십시오. 가능한 경우 DI를 사용하고 Singleton.getInstance ()를 사용해야합니다.
또한 컴파일 타임 AspectJ와 같은 하드 코어 솔루션이 기본적으로 모든 것에 Spring Bean을 짜 넣고 주입한다.
-
==============================
3.왜 네가 이걸하고 싶어하는지 모르겠다. bean에게 singleton이어야한다고 Spring에 알릴 때, 해당 클래스는 singleton 일 필요는 없으며, factory를 필요로하지 않는다. Spring은 단지 하나의 인스턴스 만 생성합니다.
왜 네가 이걸하고 싶어하는지 모르겠다. bean에게 singleton이어야한다고 Spring에 알릴 때, 해당 클래스는 singleton 일 필요는 없으며, factory를 필요로하지 않는다. Spring은 단지 하나의 인스턴스 만 생성합니다.
링크 된 기사는 아무런 의미가 없습니다. 주입이 일어나지 않아서 볼 수 있습니다. "AnyService"는 싱글 톤 팩토리 메서드를 호출합니다. 애플리케이션 컨텍스트에서 싱글 톤이 참조되는 것은 참조 될 때까지 부적절하며 다른 Bean이이를 참조하지 않는 것처럼 보입니다.
-
==============================
4.진정한 싱글 톤은 일하기가 어렵습니다.
진정한 싱글 톤은 일하기가 어렵습니다.
또한 휘발성 이중 검사 잠금은 속성을 작동하지 않습니다. wiki http://en.wikipedia.org/wiki/Double-checked_locking에서 읽어보십시오.
최선의 방법은이 작업을 간단히 수행하는 것입니다.
public class MySingleton { private static MySingleton INSTANCE = new MySingleton();
실제 코드에 생성자 매개 변수가없는 경우입니다.
-
==============================
5.나에게 이것은 벨트 앤 서스펜서 솔루션이라고 설명했다.
나에게 이것은 벨트 앤 서스펜서 솔루션이라고 설명했다.
Bean을 생성하고 그것을 구성에서 싱글 톤으로 선언하면, 다중을 생성하지 못하도록 Bean을 보호 할 필요가 없어야합니다.
기본적으로 bean을 잘못 구성한 사람으로부터 자신을 보호합니다.
개인적으로 스프링 구성 및 Javadoc의 설명서를 통해이를 "해결"합니다.
-
==============================
6.시작시 코드를 실행하고 오류가 발생하면 시작 이벤트를 등록하는 여러 가지 방법 중 하나를 사용하십시오. http://www.baeldung.com/running-setup-logic-on-startup-in-spring을 참조하십시오.
시작시 코드를 실행하고 오류가 발생하면 시작 이벤트를 등록하는 여러 가지 방법 중 하나를 사용하십시오. http://www.baeldung.com/running-setup-logic-on-startup-in-spring을 참조하십시오.
예:
@Component public class InitializingBeanExampleBean implements InitializingBean { private static final Logger LOG = Logger.getLogger(InitializingBeanExampleBean.class); @Autowired private Environment environment; @Override public void afterPropertiesSet() throws Exception { LOG.info(Arrays.asList(environment.getDefaultProfiles())); } }
from https://stackoverflow.com/questions/6205171/correct-way-of-making-a-singleton-a-spring-bean by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Framework의 주석을 통해 resourceBundle에서 지역화 된 메시지 가져 오기 (0) | 2019.01.11 |
---|---|
[SPRING] Spring을 사용하여 2 차 레벨 캐시를 최대 절전 모드로 만듭니다. (0) | 2019.01.10 |
[SPRING] Grails 파일 다운로드 (0) | 2019.01.10 |
[SPRING] Spring의 ConversionService (0) | 2019.01.10 |
[SPRING] Spring Boot Rest Controller에서 기본 JSON 오류 응답 수정 (0) | 2019.01.10 |