[spring] BeanFactory와 ApplicationContext

나는 Spring Framework를 처음 접했고, 앞으로 회사 프로젝트에 사용하기 위해 Spring MVC를 평가할 목적으로 몇 가지 샘플 앱을 모았습니다. 지금까지 나는 Spring MVC에서 보는 것을 정말 좋아하고, 사용하기가 매우 쉬우 며 테스트하기에 매우 적합한 클래스를 작성하도록 권장합니다.

실습과 마찬가지로 샘플 / 테스트 프로젝트 중 하나에 대한 주요 방법을 작성하고 있습니다. 나는 사이의 정확한 차이는 약 불분명 해요 한가지 BeanFactoryApplicationContext– 어떤 조건에서 사용하기 적합하다?

나는 그것이 ApplicationContextextends 이라는 것을 이해 BeanFactory하지만, 간단한 주요 메소드를 작성하는 경우 ApplicationContext제공 하는 추가 기능이 필요 합니까? 정확히 어떤 종류의 추가 기능을 ApplicationContext제공합니까?

“main () 메소드에서 사용해야하는”에 대한 답변 외에도 이러한 시나리오에서 어떤 구현을 사용해야하는지에 대한 표준 또는 지침이 있습니까? XML 형식으로 Bean / 응용 프로그램 구성에 따라 main () 메서드를 작성해야합니까? 안전한 가정입니까, 아니면 사용자를 특정 대상으로 잠그고 있습니까?

그리고이 대답은 웹 환경에서 변경 ApplicationContext됩니까? 내 클래스 중 하나가 Spring을 알고 있어야하는 경우 더 필요 할까요?

도움을 주셔서 감사합니다. 나는이 많은 질문이 참조 매뉴얼에서 대답 될 것이라는 것을 알고 있지만,이 두 인터페이스와 장단점을 가진 매뉴얼을 읽지 않고 각각의 장단점을 명확하게 분석하는 데 어려움을 겪고 있습니다.



답변

스프링 문서는 이것에 훌륭합니다 : 3.8.1. BeanFactory 또는 ApplicationContext? . 그들은 비교가있는 테이블을 가지고 있습니다. 스 니펫을 게시 할 것입니다.

콩 공장

  • 빈 인스턴스화 / 배선

응용 문맥

  • 빈 인스턴스화 / 배선
  • 자동 BeanPostProcessor 등록
  • 자동 BeanFactoryPostProcessor 등록
  • 편리한 MessageSource 액세스 (i18n 용)
  • ApplicationEvent 간행물

따라서 응용 프로그램 컨텍스트 측에 제시된 사항이 필요하면 ApplicationContext를 사용해야합니다.


답변

봄, IOC 컨테이너 두 종류를 제공 하나는 XMLBeanFactory다른입니다 ApplicationContext.

+---------------------------------------+-----------------+--------------------------------+
|                                       | BeanFactory     |       ApplicationContext       |
+---------------------------------------+-----------------+--------------------------------+
| Annotation support                    | No              | Yes                            |
| BeanPostProcessor Registration        | Manual          | Automatic                      |
| implementation                        | XMLBeanFactory  | ClassPath/FileSystem/WebXmlApplicationContext|
| internationalization                  | No              | Yes                            |
| Enterprise services                   | No              | Yes                            |
| ApplicationEvent publication          | No              | Yes                            |
+---------------------------------------+-----------------+--------------------------------+

여기에 이미지 설명을 입력하십시오

  • FileSystemXmlApplicationContext 콩은 전체 경로를 통해로드됩니다.
  • ClassPathXmlApplicationContext CLASSPATH를 통해로드 된 Bean
  • XMLWebApplicationContextAnnotationConfigWebApplicationContext콩은 웹 애플리케이션 컨텍스트를 통해로드.
  • AnnotationConfigApplicationContext 주석 기반 구성에서 Spring Bean로드

예:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
  • ApplicationContexta로 초기화 컨테이너 ContextLoaderListener또는 ContextLoaderServletA의 정의 web.xmlContextLoaderPlugin정의 struts-config.xml.

참고 : XmlBeanFactory됩니다 되지 찬성 봄 3.1로 DefaultListableBeanFactory하고 XmlBeanDefinitionReader.


답변

나에게 선택할 수있는 주요 차이점 BeanFactory이상은 ApplicationContext그 것 같다 ApplicationContext사전 인스턴스화 콩을 모두. 에서 문서 :

Spring은 bean이 실제로 생성 될 때 속성을 설정하고 가능한 한 늦게 의존성을 해결합니다. 이것은 객체 또는 의존성 중 하나를 생성하는 데 문제가있는 경우 객체를 요청할 때 올바르게로드 된 Spring 컨테이너가 나중에 예외를 생성 할 수 있음을 의미합니다. 예를 들어, Bean이 누락되었거나 유효하지 않은 특성으로 인해 Bean에서 예외가 발생합니다. 이로 인해 일부 구성 문제에 대한 가시성이 지연 될 수 있으므로 기본적으로 ApplicationContext 구현시 기본적으로 싱글 톤 Bean이 사전 설정됩니다. 이러한 Bean이 실제로 필요하기 전에 작성하는 데 약간의 선행 시간과 메모리가 필요하므로 나중에 ApplicationContext를 작성할 때 구성 문제를 발견 할 수 있습니다. 싱글 톤 Bean이 사전 인스턴스화되지 않고 지연 초기화되도록이 기본 동작을 계속 무시할 수 있습니다.

이를 감안할 때, 처음에는 BeanFactory격리 된 Bean을 테스트하기 위해 전체 애플리케이션을로드하고 싶지 않으므로 통합 / 성능 테스트에 사용 하기로 선택했습니다 . 그러나 내가 틀렸다면 누군가 나를 수정합니다 .XML 구성을 BeanFactory지원하지 않습니다 classpath. 그래서 BeanFactoryApplicationContext각 내가 원하는 중요한 기능을 제공하지만, 둘 모두 않았다.

내가 알 수 있듯이 기본 인스턴스화 동작을 재정의하는 것에 대한 문서의 메모는 구성에서 발생하며 빈마다이므로 XML 파일에서 “lazy-init”속성을 설정할 수는 없습니다. 테스트 용 버전과 배포 용 버전을 유지하지 못했습니다.

내가 한 일은 ClassPathXmlApplicationContext다음과 같이 테스트에 사용하기 위해 콩을 느리게로드하도록 확장 되었습니다.

public class LazyLoadingXmlApplicationContext extends ClassPathXmlApplicationContext {

    public LazyLoadingXmlApplicationContext(String[] configLocations) {
        super(configLocations);
    }

    /**
     * Upon loading bean definitions, force beans to be lazy-initialized.
     * @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
     */

    @Override
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        super.loadBeanDefinitions(reader);
        for (String name: reader.getBeanFactory().getBeanDefinitionNames()) {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) reader.getBeanFactory().getBeanDefinition(name);
            beanDefinition.setLazyInit(true);
        }
    }

}


답변

Miguel Ping이 답변 한 내용을 추가하기 위해 다음과 같은 문서의 다른 섹션 이 있습니다.

짧은 버전 : ApplicationContext를 사용하지 않는 이유가 없다면 ApplicationContext를 사용하십시오. 위의 권장 사항의 ‘그러나 왜’에 대해 약간 더 깊이를 찾는 사람들은 계속 읽으십시오.

(이 질문을 읽을 수있는 미래의 스프링 초보자를 위해 게시)


답변

  1. ApplicationContext 보다 선호되는 방법입니다 BeanFactory

  2. 새로운 Spring 버전 BeanFactory은로 대체됩니다 ApplicationContext. 그러나 여전히 BeanFactory하위 호환성을 위해 존재합니다

  3. ApplicationContext extends BeanFactory 다음과 같은 이점이 있습니다
    • 문자 메시지의 국제화를 지원합니다
    • 등록 된 리스너에 대한 이벤트 공개를 지원합니다.
    • URL 및 파일과 같은 리소스에 액세스

답변

ApplicationContext :
스프링 구성 파일에 구성된 스프링 빈을로드하고 스프링 빈의 수명주기를 관리 할 때 WHEN CONTAINER STARTS를 관리합니다. getBean ( “springbeanref”) 이 호출 될 때까지 기다리지 않습니다 .

BeanFactory
스프링 구성 파일에 구성된 스프링 빈을로드하고 getBean ( “springbeanref”)을 호출 할 때 스프링 빈의 수명주기를 관리합니다. 따라서 스프링 빈 수명주기가 시작될 때 getBean ( “springbeanref”) 을 호출 할 때 .


답변

다른 사람이 이미 말한 것처럼 모바일 환경에 있지 않는 한 항상 ApplicationContext를 사용하는 것이 좋습니다. ApplicationContext는 더 많은 기능을 가지고 있으며 Spring 구성 파일을 단순화하는 데 도움이되는 RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor 및 CommonAnnotationBeanPostProcessor와 같은 PostProcessors를 확실히 사용하고 싶어하며 Bean에서 @Required, @PostConstruct, @Resource 등의 주석을 사용할 수 있습니다 .

ApplicationContext가 제공하는 모든 것을 사용하지 않더라도 어쨌든 사용하는 것이 좋습니다. 나중에 메시지 또는 포스트 프로세서와 같은 리소스를 사용하거나 트랜잭션 스키마를 추가하기 위해 다른 스키마를 사용하기로 결정한 경우 이미 ApplicationContext가 있으며 코드를 변경할 필요가 없습니다.

독립형 앱을 작성하는 경우 ClassPathXmlApplicationContext를 사용하여 기본 메소드에서 ApplicationContext를로드하고 기본 Bean을 가져 와서 run () (또는 기타 메소드)을 호출하여 앱을 시작하십시오. 웹 응용 프로그램을 작성하는 경우 web.xml에서 ContextLoaderListener를 사용하여 ApplicationContext를 작성하고 나중에 JSP, JSF, JSTL, struts, Tapestry 등 사용 여부에 관계없이 ServletContext에서 가져올 수 있습니다. .

또한 여러 Spring 구성 파일을 사용할 수 있으며 생성자의 모든 파일을 나열하거나 ContextLoaderListener의 context-param에 파일을 나열하여 ApplicationContext를 만들거나 다음과 같은 기본 구성 파일을로드 할 수 있습니다 수입 명세서. <import resource = “otherfile.xml”/>를 사용하여 Spring 구성 파일을 다른 Spring 구성 파일로 가져올 수 있습니다. 이는 주요 메소드에서 프로그래밍 방식으로 ApplicationContext를 작성하고 하나의 Spring 구성 파일 만로드 할 때 매우 유용합니다.