스프링 빈 이란?
스프링 빈은 spring ioc 컨테이너가 관리하는 자바 객체를 빈(bean)이라고 합니다
스프링 빈이 있기전엔 java 에서 new 를 입력하거나 새로운 Class를 생성해서 new를 입력해서 원하는 객체를
직접 입력하여 관리 했습니다 코드가 지저분해지는 단점이 있었습니다.
ApplicationContext
스프링 컨테이너 입니다.
기존에 AppConfing를 생성해 구성영역을 직접 작성하여 객체 생성을 하여 의존관계를 스프링 컨테이너를 통해 사용하는것을 말합니다
스프링 컨테이너는 @Configuration이 붙은 AppConfig를 설정 정보로 사용합니다.
등록할때는 @Bean이 붙은 메서드를 호출해 반환된 객체를 스프링 컨테이너에 등록합니다.
ApplicationContext.getBean() 와 같은 메소드를 사용하며 Spring 에서 직접 자바 객체를 얻습니다
@Configuration +@ Bean
수동으로 스프링 빈을 등록할때 사용할수 있습니다.
1. 개발자가 직접 제어가 불가능한 라이브러리를 빈으로 등록할 때 불가피하게 사용합니다.
2. 유지보수성을 높이기 위해 애플리케이션 전범위적으로 사용되는 클래스나 다형성을 활용하여
여러 구현체를 빈으로 등록 할 때 사용 합니다.
3. 1개 이상의 @Bean을 제공하는 클래스의 경우 반드시 @Configuration을 명시해 주어야 싱글톤이 보장됩니다.
@Configuration 를 사용하지 않고 Bean을 사용 하면 불필요한 여러개의 빈이 생성이 될겁니다.
이문제를 방지하고자 @Configuration+@Bean 같이 씁니다.
@Configuration
static class SameBeanConfig {
@Bean
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
@Bean
public DiscountPolicy rateDiscountPolicy() {
return new RateDiscountPolicy();
}
}
}
@Configuration
public class HelloWorldConfiguration {
@Bean
public String name() {
return "Rana";
}
}
public class App02HelloSpring {
public static void main(String[] args) {
var context =
new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);
System.out.println(context.getBean("name"));
}
}
@Component
자동으로 스프링 컨테이너에 빈을 등록합니다
SpringComponent Scan 기능이 @Component 어노테이션이 있는 클래스를 자동으로 찾아서 빈으로 등록합니다
대부분의 경우 @Component를 이용한 자동 등록 방식을 사용하는 것이 좋습니다
@Component 하위 어노테이션으로 @Configuration, @Controller, @Service, @Repository 가 있습니다.
@Primary
어노테이션을 붙혀서 우선순위를 지정하는 방식입니다.
@Qualifier
스프링 컨테이너가 여러개의 빈을 찾았을 때, 추가적으로 판단할 수 있는 정보를 주는 원리입니다.
선택되는 구현체들 / 사용 하는 코드 에 @Qualifier("찾는이름")을 작성해야 합니다.
@Primray와 @Qualifier를 적절히 사용하는 것이 가장 이상적입니다.
코드에서 자주 사용하는 메인 데이터베이스 커넥션을 사용하는 빈이 있고, 코드에서 특별한 기능으로 가끔 사용하는 서브 데이터에비스의 커넥션이 있을 때
- 메인 데이터베이스 커넥션을 사용하는 빈
--> @Primary로 기본설정 - 서브 데이터에비스의 커넥션을 사용하는 빈
--> @Qualifier 지정해서 명시적으로 획득
@Component
@Primary
public class MarioGame implements GamingConsole{
public void up() {
System.out.println("Jump");
}
public void down() {
System.out.println("Go into a hole");
}
public void left() {
System.out.println("Go back");
}
public void right() {
System.out.println("Accelerate");
}
}
Component
@Qualifier("SuperContraGameQualifier")
public class SuperContraGame implements GamingConsole{
public void up() {
System.out.println("up");
}
public void down() {
System.out.println("Sit down");
}
public void left() {
System.out.println("Go back");
}
public void right() {
System.out.println("Shoot a bullet");
}
}
JAVA Bean
자바빈은 세 가지 제약 조건을 준수하는 클래스입니다.
public 기본 생성자가(no -arg생성자)가 있습니다.
getters및 setters 메소드를 사용하여 속성에 액세스할 수 있습니다.
자바 IO Serializable을 구형해야 합니다.
POJO
Plain old Java Object
제약 조건이 없습니다. 자바 클래스이기만 하면 됩니다.
그냥 만들면 오래된 방식의 간단한 자바 오브젝트가 됩니다.
모든 자바 객체는 POJO입니다.
Spring Bean
스프링 빈은 스프링이 관리하는 자바 객체입니다.
스프링은 IOC컨테이너, 빈 팩토리, 애플리케이션 컨텍스트를 사용하여 객체를 관리합니다.
IOC 컨테이너가 관리하는 객체는 모두 스프링 빈입니다.
밑부터는 참고용으로만 작성했습니다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
스프링 빈 초기화
빈을 로딩하거나 빈에서 어떤 메소드도 호출하고 있지 않지만 빈의 초기화가 자동으로 실행되는 상황이 가끔 발생합니다.
이때 @Lazy를 사용합니다.
@Lazy
많이 사용하지는 않는 어노테이션 입니다. 하지만 복잡하고 여러 초기화 로직이 주어진 경우 시작을 지연시키고 싶지 않다면 사용 합니다.
스프링 설정의 오류가 애플리케이션 시작시 발견되지 않는다는 점이 있습니다.
@Lazy 주석은 bean이 느리게 또는 주문형으로 생성되어야 함을 나타내는 데 사용됩니다. 즉, bean은 처음 사용될 때만 인스턴스화되고 초기화됩니다. 기본적으로 Spring은 애플리케이션 시작 중에 모든 빈을 열심히 생성하므로 시작 시간이 늘어나고 불필요하게 메모리를 소비할 수 있습니다.
@Lazy 어노테이션 을 사용하면 빈 생성이 완료될 때까지 Spring에 빈 생성을 연기하도록 알립니다. 이는 애플리케이션 시작 시간을 개선하고 메모리 사용량을 줄일 수 있으므로 즉시 필요하지 않은 크거나 복잡한 빈에 특히 유용할 수 있습니다.
@Component
@Lazy
public class MyLazyComponent {
// bean 속성 및 메소드
}
gpt 를 활용+강의 내용 추가를 하여 참고용으로 표를 만들었습니다.
지연된 초기화 | 이른 초기화 | |
타이밍 | 필요할 때만 Bean 생성 | 애플리케이션 시작 시 Bean 생성 |
성능 | 애플리케이션 시작 시간 및 메모리 사용량 개선 | 애플리케이션 시작 속도 저하 및 메모리 사용량 증가 |
범위 | 사용 가능 모든 빈 범위 | 일반적으로 싱글톤 또는 프로토타입 범위와 함께 사용 |
구성 | @Lazy를 사용하여 명초시적으로 활성화해야 함 (@Lazy OR2@Lazy(value=true) ) |
Spring 프레임워크의 기본 동작 @Lazy(value=flase)OR(Absence of @Lazy) (@Component가 주어졌는데 @Lazy 가 없다면 이른 초기화가 됩니다.) |
초기화 시 오류발생 경우 | 해당 오류는 런타임 예외 | 오류로 인해 애플리케이션이 시작하지 않기 때문에 애플리케이션 시작도 못함. |
종속성 주입 | 종속성 주입에 사용 가능 | 종속성에 사용 가능 주입 |
사용 | 즉시 필요하지 않은 크거나 복잡한 빈에 유용 | 즉시 필요한 빈에 유용 |
예 | @Component @Lazy 공개 클래스 MyLazyBean {...} | @Compon ent public class MyEagerBean {...} |
스프링 빈 유효 범위
Spring에서 빈의 범위는 애플리케이션 컨텍스트에서 빈의 수명 주기와 가시성을 정의합니다
bean의 범위는 생성되는 bean의 인스턴스 수와 애플리케이션 전체에서 공유되는 방법을 결정합니다.
- 싱글톤:Ioc컨테이너 마다 Bean의 인스턴스 하나만 생성되어 애플리케이션 컨텍스트에서 공유됩니다. 이것이 스프링 빈의 기본 범위입니다.
- 프로토타입: 빈의 새 인스턴스는 애플리케이션 컨텍스트에서 요청될 때마다 생성됩니다.
- 요청: 모든 HTTP 요청에 대해 빈의 새 인스턴스가 생성됩니다. 이 범위는 웹 인식 Spring 애플리케이션에만 적용할 수 있습니다.
- 세션: 빈의 새 인스턴스는 모든 HTTP 세션에 대해 생성됩니다. 이 범위는 웹 인식 Spring 애플리케이션에만 적용할 수 있습니다.
- 글로벌 세션: Bean의 새 인스턴스는 모든 글로벌 HTTP 세션에 대해 생성됩니다. 이 범위는 웹 인식 Spring 애플리케이션에만 적용 가능하며 일반적으로 포틀릿 컨텍스트에서 사용됩니다.
- 애플리케이션: Bean의 단일 인스턴스는 ServletContext당 생성됩니다 즉 전체 웹 애플리케이션당 1개의 객체 인스턴스가 생성됩니다.
- 웹 소켓: 웹 소켓 인스턴스당 1개의 객체 인스턴스를 생성 가능합니다.
빈 범위 선택은 다음에 따라 다릅니다. 응용 프로그램의 특정 사용 사례 및 요구 사항. 예를 들어 싱글톤 범위는 공유 리소
스를 나타내는 bean에 적합하고 프로토타입 범위는 stateless 개체를 나타내는 bean에 적합합니다. 요청, 세션, 전역 세션
및 웹 소켓 범위는 각각 요청, 세션 또는 연결 특정 상태를 갖는 Bean에 적합합니다.
@Scope
스프링 빈의 범위를 설정할때 사용하는 어노테이션 입니다.
@Component
@Scope("prototype")
public class MyPrototypeBean {
// Bean 속성 및 메소드
}
@Component
@Scope("prototype")
class MyPrototypeBean {
// Bean 속성 및 메소드
}
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
class PrototypeClass {
// Bean 속성 및 메소드
}
싱글톤(Singleton(GOF))
디자인 설계 패턴
Gang of Four Design Patterns라는 설계 패턴 책이 있었는대 괭장히 유명한 설계 패턴 책으로 4명의 유명한 사람들이
저술 했습니다. 설계 패턴 책에는 자바 싱글톤에 대한 설명도 있습니다. 해당 설명은 일반적으로 스프링 프레임워크와
쓰이는 싱글톤의 정의와는 조금 다릅니다
Spring 싱글톤
스프링 IoC 컨테이너당 1개의 객체 인스턴스를 말합니다 따라서 스프링 IoC 컨테이너에서는 1개의 객체 인스턴스가 주어집니다
JAVA 싱글톤
자바 가상 머신당 1개의 객체 인스턴스를 가지고 있습니다.
전체 자바 가상 머신에 오직 1개의 객체만 주어집니다.
스프링 싱글톤과 자바 싱글톤의 의미는 동일할 수 있습니다, 자바 가상머신당 1개의 스프링 IoC컨테이너만을
실행하는 경우에 동일합니다.
하지만 자바 가상 머신에서 여러 개의 스프링 IoC 컨테이너를 실행한다면 스프링 싱글톤은 자바 싱글톤과는 다릅니다.
일반적으로 자바 가상 머신당 여러 개의 스프링 IoC 컨테이너를 실행하지는 않습니다.
따라서 대부분의 상황에서 스프링 싱글톤이 자바 싱글톤과 동일하다고 할수 있습니다.
'Spring > Spring Framework' 카테고리의 다른 글
스프링 프레임워크 중요한 용어 (0) | 2023.02.27 |
---|---|
의존성주입 (0) | 2023.02.27 |
@Controller와 @RestController +@GetMapping (0) | 2023.02.19 |
스프링 강한 결합, 느슨한 결합 (0) | 2023.02.17 |
스프링 프레임워크의 기본 개념 (0) | 2023.02.13 |