Spring~Bean의 범위와 생명주기

범위

Bean의 스코프는 변수의 스코프와 다르며, '변수의 스코프'는 변수의 사용 가능한 스코프를 말하며, Bean의 스코프는 특정 행동 패턴을 말하며, 이는 다른 유형으로도 이해될 수 있습니다. 싱글톤 함수와 같은 빈 인스턴스 도메인은 전체 IoC 컨테이너에 하나의 빈만 있고 모든 작업과 반환이 이 빈임을 의미합니다.

현재 Spring에는 6가지 유형의 범위 또는 범위가 있습니다.

범위 설명하다
하나씩 일어나는 것 Singleton 범위, 전체 Spring IoC 컨테이너에 하나의 Bean 인스턴스만 있으며 Bean은 싱글톤으로 존재합니다.
원기 프로토타입 범위, 빈이 컨테이너에서 호출될 때마다 새 인스턴스를 반환합니다. 즉, getBean이 호출될 때마다 newXxxBean 메소드를 실행하는 것과 같습니다.
요구 요청 범위, 각 Http 요청은 새 Bean을 생성합니다.
세션 세션 범위, 동일한 Http 세션이 Bean을 공유하고 다른 세션이 다른 Bean을 사용합니다.
애플리케이션 Http 서블릿 컨텍스트의 전역 범위는 빈을 정의합니다.
웹 소켓(이해) WebSocket의 라이프 사이클에서 Bean 인스턴스를 정의하십시오.

일반 스프링 프로젝트에는 처음 2개의 범위만
WebApplicationContext 있고, 마지막 4개는 웹의 Spring 환경 에만 적용되는 Spring MVC의 값입니다 .

정상적인 봄 환경에서:

하나씩 일어나는 것

싱글톤으로 선언된 Bean은 전체 Spring IoC 컨테이너에서 하나의 인스턴스만 가지고 있는데 ApplicationContext.getBean을 통해 Bean을 얻거나 @Autowired 어노테이션을 통해 Bean을 어셈블하면 동일한 인스턴스를 얻는다.

Singleton은 컨테이너가 생성될 때 자동으로 객체가 생성되는 싱글톤 모드로, 사용 여부에 관계없이 이미 존재하며 매번 동일한 객체를 획득합니다. 그리고 싱글톤은 스프링의 기본 범위(기본 범위) 입니다.

일반적으로 Stateless Bean은 이 범위를 사용 하고 Stateful Bean은 프로토타입 범위를 사용합니다. Stateless는 Bean 객체의 속성을 업데이트할 필요가 없음을 의미합니다.

코드 예제:
TestSingleton 클래스를 bean으로 생성:

package com;

import org.springframework.stereotype.Component;

@Component
public class TestSingleton {
    
    
    private String message;
    public void setMessage(String message){
    
    
        this.message  = message;
    }
    public void getMessage(){
    
    
        System.out.println("Your Message : " + message);
    }
}

출력 정보가 ​​동일한지, 동일한 인스턴스인지 확인하기 위해 테스트 클래스에서 동시에 두 개의 빈을 가져오십시오.

import com.Controller.UserController;
import com.TestSingleton;
import com.User.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("a.xml");
        TestSingleton testSingleton_A=(TestSingleton)context.getBean("testSingleton");
        System.out.println("下面是第一个bean的信息:");
        testSingleton_A.setMessage("This is A!");
        testSingleton_A.getMessage();
        TestSingleton testSingleton_B=(TestSingleton)context.getBean("testSingleton");
        System.out.println("下面是第二个bean的信息:");
        testSingleton_B.getMessage();
    }
}

산출:

下面是第一个bean的信息:
Your Message : This is A!
下面是第二个bean的信息:
Your Message : This is A!

원기

빈을 프로토타입으로 선언한다는 것은 빈이 요청되거나 다른 빈에 주입될 때마다 새 인스턴스가 생성된다는 것을 의미합니다. ApplicationContext.getBean을 통해 bean을 얻거나 @Autowired 주석을 통해 bean을 어셈블하면 새 인스턴스도 얻습니다.

Prototype은 프로토타입 타입으로 컨테이너가 생성될 때 객체가 인스턴스화되지 않지만 bean을 얻으려고 할 때 객체가 생성되고 매번 획득하는 객체가 동일한 객체가 아닙니다.

상태 저장 빈은 일반적으로 프로토타입 , 즉 객체 속성을 업데이트해야 하는 빈 으로 선언 됩니다.

코드 예:

TestPrototype 클래스를 빈으로 생성하고 Scope에 주석을 달아 스코프 유형을 프로토타입으로 설정합니다.

package com;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class TestPrototype {
    
    
    private String message;
    public void setMessage(String message){
    
    
        this.message  = message;
    }
    public void getMessage(){
    
    
        System.out.println("Your Message : " + message);
    }
}

출력 정보가 ​​동일한지, 동일한 인스턴스가 동일한지, 차이점이 다른 인스턴스인지 확인하기 위해 테스트 클래스에서 두 개의 빈을 가져옵니다.


import com.TestPrototype;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("a.xml");
        TestPrototype testSingleton_A=(TestPrototype)context.getBean("testPrototype");
        System.out.println("下面是第一个bean的信息:");
        testSingleton_A.setMessage("This is A!");
        testSingleton_A.getMessage();
        TestPrototype testSingleton_B=(TestPrototype)context.getBean("testPrototype");
        System.out.println("下面是第二个bean的信息:");
        testSingleton_B.getMessage();
    }
}

산출:

下面是第一个bean的信息:
Your Message : This is A!
下面是第二个bean的信息:
Your Message : null

스프링 웹 환경에서:

request, session, application이 세 가지 범위는 Spring WebApplicationContext를 기반으로 구현 되며 웹 환경 (예: XmlWebApplicationContext) 에서만 사용할 수 있습니다.

이러한 범위가 일반적인 스프링 환경, 즉 ClassPathXmlApplicationContext 와 같은 기존 IoC 컨테이너에서 사용되는 경우 프로그램은 알 수 없는 범위가 사용되었음을 나타내기 위해 IllegalStateException을 throw합니다.

Spring에서 WebApplicationContext를 사용하는 것과 같은 웹 환경에서는 싱글톤과 프로토타입의 두 가지 범위뿐만 아니라 요청, 세션, 애플리케이션의 세 가지 고유한 범위를 사용할 수 있습니다.

웹 환경 관련 범위를 사용할 때 웹 컨테이너에서 몇 가지 추가 구성을 수행해야 합니다.

  • Spring MVC 프레임워크 를 사용하는 경우 모든 http 요청이 DispatcherServlet처리되고 DispatcherServlet관련 상태가 구성되어 있으므로 이러한 구성이 필요하지 않습니다 .
  • 웹 컨테이너의 하위 버전인 경우 구성 XML 파일에 다음 선언을 추가해야 합니다.
<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
</web-app>

Spring에서 RequestContextFilter 또는 ServletRequestListener 및 기타 메서드를 사용할 수도 있습니다. 여기에서 자세히 설명하지 않습니다.

요구

요청은 요청 범위 입니다.

Bean의 범위는 요청으로 선언되며 http 요청이 있을 때마다 새로운 인스턴스가 생성된다.

사용할 때 scope 속성에도 선언됩니다.

<bean id="" class="" scope="request"/>

이 Bean의 id가 loginAction이라고 가정하면 Spring 컨테이너는 Http 요청을 처리하기 위해 loginAction을 사용할 때마다 새로운 인스턴스를 생성할 것 입니다.

Http 요청이 범위 수준이 Request인 Bean을 호출하면 Http 요청이 추가될 때마다 Spring에서 새 Bean을 생성하고 요청이 처리되면 Bean을 소멸시키기 위해 반환되며 개발자는 상태를 임의로 변경할 수 있습니다. 각 빈은 독립적인 요청을 기반으로 하기 때문에 다른 인스턴스는 개발자가 변경한 다른 인스턴스의 상태를 볼 수 없습니다.

세션

세션은 세션 범위 입니다.

Bean은 동일한 Http Session(세션) 간에 공유되며 다른 세션은 다른 Bean을 사용합니다.

사용할 경우 범위 속성에서 선언할 수 있습니다.

<bean id="user" class="" scope="session"/>

Bean의 id가 user라고 가정하면 Spring 컨테이너가 사용자를 호출할 때마다 세션에 인스턴스를 생성합니다. 즉, Bean은 Http Session 수준에 있습니다.

Session의 모든 http 요청은 Bean을 공유하며 세션이 세션 수준 Bean으로 처리될 때마다 추가 세션마다 새 인스턴스가 생성됩니다. 위의 요청과 마찬가지로 각 Bean은 별도의 세션 세션에 따라 생성되고 다른 Bean은 이 Bean의 상태를 볼 수 없기 때문에 개발자는 Bean의 상태를 마음대로 수정할 수 있습니다.

애플리케이션

응용 프로그램은 전역 범위 입니다.

사용하는 방법:

<bean id="app" class="" scope="application"/>

Bean의 id가 app이라고 가정하면 Spring 컨테이너는 웹 애플리케이션 전체에서 앱이 사용될 때 새 인스턴스를 생성합니다. 즉, appBean은 ServletContext 레벨에 있습니다. .

전역 범위와 싱글톤 범위는 다릅니다.

ServletContext의 일반 속성으로 전역 범위는 Spring의 싱글톤 범위와 유사하지만 차이점이 있습니다.

  • 다른 소스 : 싱글톤은 Spring Core에서, 애플리케이션은 Spring Web에서 가져옴
  • 다른 사용법 : IoC 컨테이너는 싱글톤을 사용하고 서블릿 컨테이너는 애플리케이션을 사용합니다.

빈의 범위를 선언하는 방법

xml 구성 파일을 통해

xml 설정 파일에서 Bean 요소의 범위 속성을 직접 설정할 수 있다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
     //scope属性
    <bean id="SingletonBean" class="com.spring.demo.SingletonBean" scope="prototype"></bean>
   
</beans>

주석을 통해

Bean에 주석을 추가합니다.

package com.spring.demo;
 
import org.springframework.context.annotation.Scope;;
import org.springframework.stereotype.Component;
 
@Component("SingletonBean")
@Scope("prototype")
public class SingletonBean {
    
    
    private String message;
    public void setMessage(String message){
    
    
        this.message  = message;
    }
    public void getMessage(){
    
    
        System.out.println("Your Message : " + message);
    }
}

@Component("SingletonBean")은 클래스를 빈으로 식별하고 @Scope("prototype")는 빈의 범위를 프로토타입 유형으로 식별합니다.

라이프 사이클

빈의 라이프 사이클은 "생성"에서 "파괴"까지의 빈 객체의 프로세스를 말하며,
빈 정의 --> 빈 초기화 --> 빈 사용 --> 빈 소멸로 표현될 수 있습니다.

구체적인 과정은 다음과 같습니다.

1. Bean을 인스턴스화하고 Bean에 대한 메모리 공간을 할당합니다.
2. 속성 설정, 빈 주입 또는 어셈블
3. 초기화:

  • BeanNameAware, BeanFactoryAware, BeanFactoryAware, ApplicationContextAware 등과 같은 다양한 알림(Aware) 메소드를 구현합니다.
  • BeanPostProcessor초기화 사전 메소드 실행
  • @PostConstruct 초기화 메소드 실행 및 의존성 주입 후 실행
  • 사용자 정의 내부 메서드 실행(선택 사항)
  • BeanPostProcessor초기화 포스트 메소드를 실행합니다 .
    4. 콩 사용
    5. 콩 파괴

순서도는 다음과 같습니다.
여기에 이미지 설명 삽입

초기화와 인스턴스화의 차이점:

인스턴스화 및 속성 설정은 Java의 시스템 이벤트로 간섭 및 수정이 불가능하며 초기화는 개발자가 커스터마이즈 하며 인스턴스화 완료 후 클래스가 로드되기 전에 이러한 커스터마이즈된 초기화 내용이 실행됩니다.

기사 참조: https://blog.csdn.net/kongmin_123/article/details/82048392

추천

출처blog.csdn.net/Merciful_Lion/article/details/124082956