1. WAR 파일

WAR(WEB Application aRchive) 파일은 웹 애플리케이션을 Java EE 서버에서 실행하기 위해 사용되는 형식입니다. 이 파일은 JSP, HTML, javascript, css, image, xml, java 클래스, java 라이브러리 등 웹 애플리케이션을 구성하는 모든 파일을 포함하고 있습니다. 이 파일은 웹 서버가 애플리케이션을 배포하고 실행하는 데 필요한 구조와 메타데이터를 가지고 있습니다.
  • 자바 설치
  • 웹/애플리케이션 서버 설치
  • 애플리케이션의 WAR 배포

2. JAR 파일

JAR(Java ARchive) 파일은 Java 클래스 파일, 관련 메타데이터 및 리소스를 하나의 파일로 묶은 것입니다. 이는 일반적으로 라이브러리나 실행 가능한 Java 애플리케이션으로 사용됩니다. JAR 파일은 플랫폼 독립적이며, Java Virtual Machine(JVM)에서 직접 실행할 수 있습니다.
  • 자바 설치
  • JAR 파일 실행 (임베디드 서버 사용) 
    • Spring-boot-starter-tomcat 톰캣
    • Spring-boot-starter-jetty 제티
    • Spring-boot-starter-Undertow 언더토우
    • https://suhanlim.tistory.com/247 각 웹서버 정리

 

1. 프로젝트 경로로 이동

2. cmd에서 gradlew build 명령어 실행

Mac OS 기준: ./gradlew clean build 명령어 실행

3. build -> libs 디렉토리 확인

4. cmd에 java -jar 파일명.jar 입력시 실행

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

Controller, Service, Repository 분할  (0) 2023.05.26
Spring Boot Starter Actuator을 이용해 지금까지의 접근 횟수 보기  (0) 2023.05.23
엔티티 매핑  (0) 2023.04.27
영속성 컨텍스트  (0) 2023.04.24
빈 스코프  (0) 2023.03.21

객체와 테이블 매핑 방법

  • @Entitiy: JPA가 관리 하는 엔티티로 등록
    • 속성 name: JPA에서 사용할 엔티티 이름을 지정 디폴트 값은 클래스의 이름
  • @Table
    • 속성 name: 데이터 베이스에 연결될 테이블의 이름 설정
  • 조건
    • 기본 생성자 필수
    • final 클래스 enum, interface, inner 클래스 사용 x
    • 저장할 필드에 final 상용 x

데이터베이스 스키마 자동 생성

<property name="hibernate.hbm2ddl.auto" value="create" />
  • 애플리케이션 로딩 시점에 Create문으로 DB 생성
  • 데이터베이스 방언을 활용해 데이터베이스에 맞는 적절한 DDL 생성
  • 주의점
    • 운영 장비에서는 절대 ceate, create-drop, update 사용하면 안된다.
    • 개발 초기 단계는 create 또는 update
    • 테스트 서버는 update 또는 vaildate
    • 스테이징과 운영 서버는 vaildate 또는 none

필드와 컬럼 매핑

  • @Column(name = "EntityName")
    • updateble: 업데이트 반영 여부 결정 기본값은 true
    • nullable: 널타입 여부 제약조건 설정
    • unique: SQL문의 unique제약 조건
  • @Enumerated: enum 타입 매핑
  • @Temporal
    • DATE: 날짜
    • TIME: 시간
    • TIMESTAMP: 날짜, 시간 둘다 
  • @Lob: barchar을 뛰어넘는 큰 값이 필요로 할 때 사용
    • 문자열에 대응시 Clob으로 생성  
    • 나머지 Blob으로 생
  • @Transient: DB에 올라가지는 않고 메모리에서만 사용하고 싶을 때 사용 

기본 키 매핑

  • @Id

연관관계 매핑

  • @ManyToOne
  • @JoinColumn

정의

  • JPA 작업 결과를 DB에 반영 하기 위해 사용되는 일종의 캐시(cache)로 엔티티(Entity) 객체를 관리하며, DB와 동기화 되는 별도의 공간 
  • JPA를 이해하는데 가장 중요한 용어
    • JPA: DB의 SQL 작업을 객체로 취급하여 작업하는 것
  • 엔티티를 영구 저장하는 환경
    • 구성요소: 1차 캐쉬, 쓰기 지연 SQL 저장소
  • 논리적인 개념으로 눈에 보이지 않는다.
  • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근
    • 엔티티 매니저(EntityManager) 생성시 1대1 영속성 컨텍스트(PersistenceContext)가 생성 (J2SE 환경)

엔티티의 생명주기

  • 비영속: 영속성 컨텍스트와 전혀 관계가 없는 생성만 한 상태
Item item = new Item();
item.setName("doll");
item.setPrice("10000");
item.setId("150L");
  • 영속: 영속성 컨텍스트에 관리되는 상태
    • 실제로 DB에 저장되는 것은 아직 아님 !
Item item = new Item();
item.setName("doll");
item.setPrice("10000");
item.setId("150L");

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("UnitName");
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
// 영속
em.persist(item);
  • 준영속: 영속성 컨텍스트에 저장되었다가 분리된 상태
    • 이후 commit을 하더라도 해당 속성의 엔티티의 관련된 쿼리문은 나가지 않는다.
em.detach(member); // 특정 엔티티만 준영속 상태로 전환
em.clear(); // 영속성 컨텍스트를 완전히 초기화
em.close(); // 영속성 컨텍스트를 종료
  • 삭제: 삭제된 상태
em.remove(member);

데이터 조회 과정

  • 영속성 컨텍스트 내부의 1차 캐쉬 탐색
  • 연결된 DB 탐색
  • 그 후 탐색된 값을 1차 캐쉬에 저장
  • 이때 조회된 데이터는 동일성을 보장한다. (1차 캐쉬 덕분)
Item item1 = em.find(Item.class, 150L);
Item item2 = em.find(Item.class, 150L);

System.out.println(item1==item2); // true 출력

데이터 삽입 과정

  • EntityManager.persist("Item")실행시 1차 캐시에 저장
  • JPA가 Unit를 분석하여 쿼리문을 자동 생성
  • 해당 쿼리문을 쓰기 지연 SQL 저장소에 저장
  • EntityTransaction.commit() 시 해당 쿼리문 DB에 전송(flush)
    • 해당 작업이 있는 이유: 추가적으로 최적화 할 수 있는 여지가 생기기 때문
  • 실제 데이터 베이스 트랜잭션 commit

데이터 변경 과정(삭제도 동일)

Item item = em.find(Item.class,150L);
            item.setName("Rock");
tx.commit();
  • 영속성 컨텍스트 내부에서 flush() 실행
    • flush는 쓰기 지연 SQL 저장소에 있는 쿼리를 DB에 반영하는 행위
  • 1차 캐쉬에서 엔티티와 스냅샷을 비교
  • 바뀐 내용이 있다면 업데이트 SQL문을 쓰기 지연 SQL 저장소에 저장
  • 쿼리문 DB에 전송
  • 실제 데이터 베이스 트랜잭션 commit

플러시(flush)

  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하는 것
    • 영속성 컨텍스트와 데이터 베이스의 데이터를 동기화
  • 트랜젝션이 commit될때 일어난다.
  • 과정 (1차 캐쉬의 내용을 건들지는 않는다)
    • 변경 감지
    • 수정된 엔티티 쓰기 지연 sql 저장소에 등록
    • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
  • 사용법
    • em.flush() 호출
    • 트랜션 커밋
    • JPQL 쿼리 실행
  • 플러시 모드 옵션
    • FlushModeType.AUTO: 커밋이나 쿼리를 실행할 때 플러시 (디폴트 설정)
    • FlushModeType.CUMMIT: 커밋을 할 때만 플러시

학습 자료 출처: https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

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

Spring Boot Gradle JAR 파일 생성 실행  (0) 2023.05.23
엔티티 매핑  (0) 2023.04.27
빈 스코프  (0) 2023.03.21
빈 생명주기 콜백  (0) 2023.03.20
다양한 의존관계 주입 방법  (0) 2023.03.19

빈 스코프

  • 스프링 빈은 기본적으로 싱글통 스코프(빈이 존재할 수 있는 범위)로 생성된다.
  • 빈 스코프 종류
    • 싱글톤: 기본 스코프, 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프
    • 프로토타입: 스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입까지만 관야하고 더는 관리하지 않는 매우 짧은 범위의 스코프이다.
    • 웹 관련 스코프
      • request: 웹 요청이 들어오고 나갈때 까지 유지되는 스코프이다.
      • session: 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프이다.
      • application: 웹의 서블릿 컨텍스와 같은 범위로 유지되는 스코프이다.

프로토타입 스코프

  • 싱글톤 스코프의 빈과 다르게 프로토타입 스코프는 스프링 컨테이너에서 조회하면 항상 새로운 인스턴스를 생성해서 반환한다. 그후 스프링 컨테이너는 해당 빈을 관리하지 않는다.
  • 프로트타입 빈을 관리할 책임은 프로토타입 빈을 받은 클라이언트에 있다 그래서 @PreDestory 같은 종료 메서드가 호출되지 않는다.
    • 만약 destory 메소드 호출이 필요하다면 직접 호출하여 사용해야 한다.
  • 싱글톤 빈과 같이 사용시 문제점
    • 상황: sigleton으로 등록된 Bean이 prototype으로 등록된 빈을 의존하고 있는 경우
    • 복수의 클라이언트가 해당 기능을 사용할 시 SingletonBean이 내부에 가지고 있는 PrototypeBean은 이미 과거에 주입이 끝난 빈이기 때문에 기존의 값을 그대로 가지고 있어 잘못된 값을 가져오게 된다.
  • 해결법: 의존관계 조회(탐색) DL
    • 싱글톤 빈이 프로토타입 빈을 사용할 때 마다 스프링 컨테이너에 새로 요청하는 방법. (==빈의 생성을 지연하는 방법)
      • ObjectProvider<PrototypeBean> 스프링 표준
    @Autowired
    private ObjectProvider<PrototypeBean> prototypeBeanProvider;
    
    public int logic(){
                PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
                prototypeBean.addCount();
                return prototypeBean.getCount();
    }
    
    • JSR-330 Provider
      • jakarta.inject.Provider 자바 표준
    @Autowired
            private Provider<PrototypeBean> prototypeBeanProvider;
            public int logic(){
                PrototypeBean prototypeBean = prototypeBeanProvider.get();
                prototypeBean.addCount();
                return prototypeBean.getCount();
            }
    

웹 스코프

  • 특징:
    • 웹 환경에서만 동작하는 빈이다.
    • 웹 스코프틑 프로토타입과 다르게 스프링이 스코프의 종료시점까지 관리한다.
  • 종류
    • request: HTTP 요청 하나가 들어오고 나갈 때 까지 유지되는 스코프, 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고, 관리된다.
      • HTTPrequest 요청 마다 각각 빈이 할당된다. (단 같은 클라이언트의 요청이면 동일한 빈이 사용됨)
      • @Scope(value = "request",proxyMode = ScopedProxyMode.TARGET_CLASS) 해당 기능을 사용하여 프록시객체(가짜 객체)를 사용하여 마치 싱글톤 빈 처럼 사용이 가능하다.
        • 단지 애노테이션 설정 변경만으로 원본 객체를 프록시 객체로 대체할 수 있다. 이것이 바로 다형성과 DI 컨테이너가 가진 큰 장점이다.
    • session: HTTP Session과 동일한 생명주기
    • application: 서블릿 컨텍스트와 동일한 생명주기를 가지는 스코프
    • websocket: 웹 소켓과 동일한 생명주기를 가지는 스코프

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

엔티티 매핑  (0) 2023.04.27
영속성 컨텍스트  (0) 2023.04.24
빈 생명주기 콜백  (0) 2023.03.20
다양한 의존관계 주입 방법  (0) 2023.03.19
컴포넌트 스캔과 의존관계 자동주입  (0) 2023.03.18

빈 생명주기 콜백 시작

  • 에플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화와 종료 작업이 필요하다.
  • 스프링 빈은 모든 객체를 생성한 후 의존관계를 주입하는 라이프사이클을 가진다.
  • 따라서 스프링 빈은 객체를 생성하고, 의존관계 주입이 다 끝난 다음에야 필요한 데이터를 사용할 수 있는 준비가 완료된다.
    • 개발자가 의존관계 주입이 모두 완료된 시점을 어떻게 알 수 있을까?
      • 소멸전 콜백: 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 준다
      • 초기화 콜백: 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려준다.
      • 해당 콜백을 받는 방법에는 3가지가 존재한다.
  • 스프링 빈의 이벤트 라이프사이클
    • 스프링 컨테이너 생성
    • 스프링 빈 생성
    • 의존관계 주입
    • 초기화 콜백
    • 사용
    • 소멸전 콜백
    • 스프링 종료
  • 객체의 생성과 초기화를 분리하자
    • 객체 내부에 값을 세팅 하는 정도만 생성자에서 하는게 좋다.
    • 무거운 작업은 별도의 외부 작업으로 나누는 것이 좋다.

인터페이스로 콜백을 받는 방법(거의 사용되지 않는다)

  • implements InitializingBean
  • @Override // 의존 관계 주입 후 호출 public void afterPropertiesSet() throws Exception { }
  • implements DisposableBean
  • @Override // 빈 종료시 호출 public void destroy() throws Exception { }
  • 단점:
    • 내가 코드를 고칠 수 없는 외부 라이브러리에는 적용할 수 없다
    • 초기화 소멸 메서드의 이름을 변경할 수 없다.
    • 스프링 전용 인터페이스 임으로 해당 코드가 스프링 전용 인터페이스로 구현되어야 한다.

빈에 등록

    // 의존 관계 주입 후 호출
    public void **init()** throws Exception {
        System.out.println("NetworkClient.init");
        connect();
        call("초기화 연결 메시지");
    }

    // 빈 종료시 호출
    public void **close()** throws Exception {
        System.out.println("NetworkClient.close");
        disconnect();
    }
  • @Bean(initMethod = "init", destroyMethod = "close")
    • destoryMethod 는 디폴트로 추론 기능을 가지고 있어서 따로 메소드 이름을 입력하지 않아도 자동으로 호출된다. destroyMethod = ""
  • 장점:
    • 메서드 이름을 자유롭게 줄 수 있다.
    • 스프링 빈이 스프링 코드에 의존하지 않는다.
    • 코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.

에노테이션 (추천 방법)

    @PostConstruct// 의존 관계 주입 후 호출
    public void init() throws Exception {
        System.out.println("NetworkClient.init");
        connect();
        call("초기화 연결 메시지");
    }

    @PreDestroy// 빈 종료시 호출
    public void close() throws Exception {
        System.out.println("NetworkClient.close");
        disconnect();
    }
  • 장점:
    • 애노테이션 하나만 붙이면 되므로 매우 편리하다.
    • 컴포넌트 스캔과 잘 어울린다.
  • 단점:
    • 외부 라이브러리에는 적용하지 못 한다. 이때는 @Bean의 기능을 사용하자.

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

영속성 컨텍스트  (0) 2023.04.24
빈 스코프  (0) 2023.03.21
다양한 의존관계 주입 방법  (0) 2023.03.19
컴포넌트 스캔과 의존관계 자동주입  (0) 2023.03.18
웹 애플리케이션과 싱글톤  (0) 2023.03.15

생성자 주입(권장)

  • @RequiredArgsConstructor Lombok의 어노테이션을 통해 생성자 코드를 작성하지 않아도 똑같은 기능을 제공하는 것이 가능하다.
  • 생성자를 통해서 의존관계를 주입 받는 방법
  • 특징:
    • 생성자 호출시점에 딱 1번만 호출되는 것이 보장된다.
    • 불변, 필수 의존관계에 사용
      • final 키워드를 통해 생성자 or 선언 할 때 지정한 값으로 고정 시키는 것 이 가능하다.
    • 빈에 등록시 의존관계 주입이 자동으로 일어난다
    • 프레임워크에 의존하지 않고 순수한 자바의 장점을 잘 이용하는 것
  • 생성자가 딱 1개만 있으면 @Autowired를 생략해도 자동 주입된다. (스프링 빈에서만)

수정자 주입

  • setter을 사용하여 의존관계 주입
  • 특징:
    • 선택, 변경 가능성이 있는 의존관계에 사용
    • 순수한 자바 코드이기때문에 메서드 호출 방식이 필요하다

필드 주입 (비추천)

  • 필드변수에 @Autowired 어노테이션을 붙여서 의존관계를 주입
  • 코드가 간결하지만 외부에서 변경이 불가능하여 테스트 하기 힘들다는 단점이 있다
  • DI 프레임 워크가 없으면 아무것도 할 수 없다.

일반 메서드 주입

  • 일반 메서드를 호출하여 의존성을 주입
  • 사실 수정자 주입이랑 비슷하다.
  • 특징
    • 한번에 여러 필드를 주입 받을 수 있다.
    • 일반적으로 잘 사용하지 않는다.

<학습 강의>

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

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

빈 스코프  (0) 2023.03.21
빈 생명주기 콜백  (0) 2023.03.20
컴포넌트 스캔과 의존관계 자동주입  (0) 2023.03.18
웹 애플리케이션과 싱글톤  (0) 2023.03.15
스프링 컨테이너와 스프링 빈  (0) 2023.03.14

컴포넌트 스캔

  • 스프링은 설정 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다.
  • 또 의존관계도 자동으로 주입하는 @Autowired 라는 기능도 제공한다.
  • 컴포넌트 스캔을 사용하려면 먼저 @ComponentScan 을 설정 정보에 붙여주면 된다.
  • 컴포넌트 스캔은 이름 그대로 @Component 에노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다.
  • @Autowired 어노테이션을 생성자에 명시해두면 Spring이 자동으로 해당 스프링 빈을 찾아서 의존관계를 주입해준다
  • AnnotationConfigApplicationContext를 쓰는건 똑같다
  • @ComponentScan 는 @Component가 붙은 모든 클래스를 스프링 빈으로 등록한다.
  • 이때 스프링 빈의 기본 이름은 클래스명을 사용하되 맨 챂글자만 소문자를 사용한다.
    • 빈 이름 기본 전략: Member → member
    • 빈 이름 수동 수정: @Component("memberService") → memberService

컴포넌트 스캔의 탐색 위치와 기본 스캔 대상

@ComponentScan(
        basePackages = "hello.core.member",
				basePackageClasses = AutoAppConfig.class,
)
  • hello.core.member의 패키지를 포함한 하위 패키지들만 빈에 등록 됨
  • AutoAppConfig.class에서도 빈에 등록될 클래스 탐색
  • 만약 아무런 지정 없이 디폴트 라면?: 해당 어노테이션이 있는 설정 정보 패키지 부터 해서 하위 패키지들을 전부 탐색하여 빈으로 등록함
  • 권장하는 방법: 패키지 위치를 지정하지 않고, 설정 정보 클래스의 위치를 프로젝트 최상단(시작위치)에 두는 것, 최근 스프링 부트도 이 방법을 기본으로 제공한다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication
  • @SpringBootApplication 설정 안에 @ComponentScan 가 들어있다
  • @ComponentScan 을 사실상 사용할 필요가 없는 이유도 @SpringBootApplication 가 전부 해당 기능을 실행시키기 때문이다.

컴포넌트 스캔 기본 대상

  • 컴포넌트 스캔은 @Component 뿐만 아니라 다음과 같은 내용도 추가로 대상에 포함한다.
    • @Component: 컴포넌트 스캔에서 사용
    • @Controller: 스프링 MVC 컨트롤러에서 사용
    • @Service: 스프링 비지니스 로직에서 사용
    • @Repository: 스프링 데이터 접근 계층에서 사용
    • @Configuration: 스프링 설정 정보에서 사용

중복 등록과 충돌

  • 컴포넌트 스캔에 의해 자동으로 스프링 빈에 등록되는데 중복되는 이름이면 충돌이 발생한다.
    • 수동 빈 등록과 자동 빈 등록의 이름이 같은 경우
      • 정말 잡기 어려운 버그가 만들어진다.
      • 그래서 최근 스프링 부트에서는 수동 빈 등록과 자동 빈 등록이 충돌이남녀 오류가 발생하도록 기본 값을 바꾸었다.

<학습 자료>

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

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

빈 생명주기 콜백  (0) 2023.03.20
다양한 의존관계 주입 방법  (0) 2023.03.19
웹 애플리케이션과 싱글톤  (0) 2023.03.15
스프링 컨테이너와 스프링 빈  (0) 2023.03.14
IoC, DI, 그리고 컨테이너  (0) 2023.03.14

자바 예시 코드

public class SingletonService {
    private static final SingletonService instance = new SingletonService();
    
    public static SingletonService getInstance(){
        return instance;
    }
		private SingletonService(){

    }
}

필요성

  • 웹 애플리케이션은 동시에 많은 사용자가 이용한다. 이때 각각의 경우마다 새로운 인스턴스를 생성하는 건 비효율적이고 문제가 있다.
    • 따라서 싱글톤 기법으로 작성해둬야 할 필요가 있다.

문제점

  • 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
  • 의존관계상 클라이언트가 구체 클래스에 의존한다 → DIP를 위반한다.
  • 테스트를 하기 어렵다.
  • 내부 속성을 변경하거나 초기화 하기 어렵다.
  • private 생성자로 자식 클래스를 만들기 어렵다.
  • 결론적으로 유연성이 떨어진다.
  • 안티패턴으로 불리기도 한다.

Spring에서의 싱글톤

  • 스프링 컨테이너를 사용하면 Bean에 등록된 모든 클래스를 싱글톤 패턴으로 관리해 주기 때문에 일일이 싱글톤으로 선언 할 필요가 없다.

스프링 컨테이너

  • 스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, Bean 저장소에 등록된 객체 인스턴스를 싱글톤으로 관리한다.
  • 싱글톤 컨테이너의 역활을 한다. (싱글톤 레지스터 기능)
  • 싱글톤 패턴을 위한 지저분한 코드가 들어가지 않아도 된다.
  • DIP, OCP, 테스트, private 생성자로 부터 자유롭게 싱글톤을 사용 할 수가 있다.
  • @Configuration 어노테이션으로 등록된 클래스 그대로 등록 되는 것이 아니라 CGLIB라는 바이트코드 조작 라이브러리가 해당 클래스를 상속받은 임의의 다른 클래스를 만들고 그 다른 클래스를 Spring Bean으로 등록한다
    • 주의: @Bean만 사용해도 스프링 빈으로 등록되지만, 싱글톤을 보장하지 않는다 따라서 꼭 @Configuration 어노테이션을 사용해주어야 한다.

싱글톤 방식의 주의점

  • 객체 인스턴스 하나만 생성해서 공유하는 방식은 여러 클라이언트가 같은 객체 인스턴스를 공유하기 때문에 싱글톤 객체는 상태를 유지(statefull)하게 설계하면 안된다.
  • 무상태(stateless)로 설계해야 한다.
    • 특정 클라이언트에 의존적인 필드가 있으면 안된다.
    • 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다.
    • 가급적 읽기만 가능하도록 해야 한다.
    • 필드 대신에 자바에서 공유되지 않는, 지역변수, 파라미터 등을 사용해야 한다.
  • 스프링 빈의 필드에 공유 값을 설정하면 정말 큰 장애가 발생할 수 있다.
  • @Configuration과 @Bean의 조합으로 싱글톤을 보장하는 경우는 정적이지 않은 메서드일 때이다 즉 static 선언으로 정적 메소드로 선언되어 있다면 싱글톤을 보장받지 못 한다.

 

<학습 강의>

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

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

다양한 의존관계 주입 방법  (0) 2023.03.19
컴포넌트 스캔과 의존관계 자동주입  (0) 2023.03.18
스프링 컨테이너와 스프링 빈  (0) 2023.03.14
IoC, DI, 그리고 컨테이너  (0) 2023.03.14
스프링  (0) 2023.03.12

+ Recent posts