전체 글 150

컴포넌트 스캔

@Bean이나 등의 설정 정보를 통해서 스프링 빈을 등록하는 방식은 스프링 빈이 많아 지면 귀찮기도 하고 누락될 수도 있다. 그래서 설정 정보가 없어도 자동으로 스프링 빈이 등록되는 컴포넌트 스캔이라는 기능을 제공한다. 컴포넌트 스캔을 사용하기 위해 Config 파일을 만들어 보자. @Configuration @ComponentScan public class AutoAppConfig { } Config 파일에는 @Configuration, @ComponentScan 두개의 애노테이션이 필요하다. 이전의 설정 정보를 이용해서 스프링 빈을 등록하는 AppConfig와는 다르게 @Bean으로 등록한 클래스가 없다. 컴포넌트 스캔은 @Component 애노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록해 준..

스프링 2023.07.17

싱글톤 방식의 주의점

객체 인스턴스를 하나만 만들어서 공유하여 사용하는 싱글톤 방식의 객체는 상태를 stateful 하게 설계하면 안 된다. stateless 하게 설계해야 한다. 즉 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안 되고, 특정 클라이언트에 의존적인 필드가 있으면 안 된다. 필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal 등을 사용해야 한다. 문제점 예시를 보자 public class StatefulService { private int price; // 상태를 유지하는 필드, 공유되는 필드 public void order(String name, int price) { System.out.println("name = " + name + " privce = " +price..

스프링 2023.07.11

싱글톤 패턴, 싱글톤 컨테이너

웹 애플리케이션은 보통 여러 고객이 동시에 요청하는데 요청할 때마다 스프링 없는 순수한 DI 컨테이너는 객체를 생성해 준다. @Test @DisplayName("스프링 없는 순수한 DI 컨테이너") void pureContainer() { AppConfig appConfig= new AppConfig(); //1. 조회 : 호출할 때 마다 객체를 생성 MemberService memberService1 = appConfig.memberService(); //2. 조회 : 호출할 때 마다 객체를 생성 MemberService memberService2 = appConfig.memberService(); //참조값이 다른 것을 확인 Assertions.assertThat(memberService1).isNo..

스프링 2023.07.11

XML로 스프링 컨테이너 설정 정보 사용하기

스프링 컨테이너는 다양한 형식의 설정 정보를 받아들릴 수 있게 설계되어 있다. 그중 XML로 설정해 보자 XML로 설정하기 위해선 AnnotationConfigApplicationContext 대신 GenericXmlApplicationContext를 사용해야 한다. ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml"); 그다음 appConfig.xml을 만들어 주어야 한다. xml에서 bean을 설정할 때 id, class를 작성해 주면 된다. 생성자로 의존성을 주입하려면 태그를 이용하면 된다. 속성으로 name, ref를 사용한다 name : 매개변수명으로 연결한다. (기존의 변수명과 동일해야 된다) ref :참조 자료형을..

스프링 2023.07.10

스프링 빈 조회하기

스프링 컨테이너에서 스프링 빈을 조회하는 기본적인 방법 ac.getBean(빈이름, 타입) ac.getBean(타입) 스프링 빈이 없으면 예외가 발생한다 NoSuchBeanDefinitionException 구체 타입으로도 조회할 수 있는데 유연성이 떨어진다. 빈이 존재하지 않을 때는 assertThrows에 NoSuchBeanDefinitionException.class 에러로 테스트 코드를 작성해야한다. 여기서의 Assertions은 junit의 Assertions을 사용한다. 동일한 타입이 둘 이상인 경우 이렇게 동일한 MemberRepository에 대해 타입이 두개인 경우 NoUniqueBeanDefinitionException이 발생한다. 이 경우에는 빈 이름을 지정하면 해결이 된다. 특정 타..

스프링 2023.07.10

스프링 컨테이너 생성 과정

스프링 컨테이너 생성 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); 스프링 컨테이너에는 스프링 빈 저장소가 있는데 여기엔 빈 이름과 빈객체를 테이블로 저장한다. 그 후 인자로 넘어온 AppConfig.class의 구성 정보를 활용한다. AppConfig.class의 Bean으로 설정된 것들을 스프링 빈 저장소에 저장한다. 여기서 빈 이름은 메서드의 이름인데 이를 직접 부여할 수 도 있다. 하지만 이는 잘 사용하지 않는다고 한다. 여기서 빈 이름은 항상 다른 이름을 부여해야 한다. 그 후 스프링 빈 의존관계를 설정 정보를 참고해서 주입한다. 출처 : 인프런 스프링 핵심 원리 - 기..

스프링 2023.07.10

AppConfig에서 스프링으로 전환하기

스프링으로 전환하기 위해서는 어노테이션을 붙여주어야 한다 이제 AppConfig를 이용하여 주입했던 부분을 주석 처리하고 스프링을 이용하자 ApplicationContext는 스프링의 컨테이너이다. AnnotationConfigApplicationContext는 Annotation 기반의 자바 설정 클래스로 스프링 컨테이너를 만든다 @Configuraion이 붙은 설정 정보를 사용한다. 인자로 AppConfig.class를 넘겨주어서 AppConfig를 활용하여 등록한다. 여기에 있는 @Bean이 붙은 함수들의 반환 객체들을 다 등록시킨다. 이때 빈의 이름은 함수의 이름을 사용한다. 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다. getBean 함수를 통해 DI를 해준다. 이때 함수는 두 개의 인..

스프링 2023.07.10

AppConfig

https://salmon16.tistory.com/75 OCP, DIP 원칙이 위배되는 역할과 구현 분리 역할과 구현을 분리하고 다형성을 이용하여 잘 설계를 해도 OCP, DIP 원칙을 위반할 수 있다 . 아래 예시를 보자 OrderServiceImpl은 DiscountPolicy라는 인터페이스에 의존하면서 DIP를 잘 지킨 것 같지만 salmon16.tistory.com 위 링크 문제를 해결하기 위해 구현 객체를 생성하고 연결하는 AppConfig클래스를 만들자. Appconfig는 구현 객체를 생성하여 return 해 준다. 이렇게 작성을 하고 각 Impl클래스의 생성자를 추가하면 OCP, DIP를 위배하지 않게 만들 수 있다. 예로 MemberServiceImpl 코드를 보면 더 이상 구현에 의존..

스프링 2023.07.06

OCP, DIP 원칙이 위배되는 역할과 구현 분리

역할과 구현을 분리하고 다형성을 이용하여 잘 설계를 해도 OCP, DIP 원칙을 위반할 수 있다 . 아래 예시를 보자 OrderServiceImpl은 DiscountPolicy라는 인터페이스에 의존하면서 DIP를 잘 지킨 것 같지만 구현 클래스(Fix, Rate DiscountPolicy)에도 의존하고 있다 그러므로 FixDiscount에서 RateDiscount로 변경하려면 OberServiceImpl 코드를 변경 해야한다 (FixDiscountPolicy주석 처리하고 RateDiscountPolicy 할당) 기대했던 의존관계는 OrderServiceImpl는 DiscountPolicy인터페이스만 의존하기를 원했다 그렇다고 코드를 아래와 같이 수정을 하면 구현체가 없어서 null point except..

스프링 2023.07.06