스프링 소스의 원칙 기사 (A)

스프링 소스의 원칙 장 - 컨테이너 초기화 및 콩 포스트 프로세서

IOC 컨테이너는 일반적으로 몇 가지 작업 및 작업 원칙과 하단에있는 포스트 프로세서 콩 BeanPostProcessor를 수행이 장 쇼 초기화 과정에서 설명합니다.

환경 준비

  • 컴파일러 IDEA
  • 받는다는依赖스프링 상황에 맞는 버전 : 4.3.12.RELEASE
  • Maven은의 JUnit에 의존 버전 : 4.11

있는 BeanPostProcessor 작품

BeanPostProcessor 인터페이스 구현 성분 및 생체 내에서 두 개의 브레이크 포인트로 표시 :

public class BeanPostProcessorDefinition implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessBeforeInitialization -->"+s+" = "+o);
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessorAfterInitialization -->"+s+"="+o);
        return o;
    }
}
复制代码

다음 (그림 1) 메서드 호출 스택을 시운전 후 확인 :

스택 initializeBean (초기화 콩) 메서드 호출 방법은 다음 의사 코드와 유사한 있습니다 :

initializeBean(param){
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
...
invokeInitMethods(beanName, wrappedBean, mbd);
...
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
复制代码

이것은 일반적으로 제 의사 코드 초기화 마지막 실행 후 초기화 방법 콩 및 콩 초기화 처리 공정 전에 수행되는 것을 의미한다. applyBeanPostProcessorsBeforeInitialization 호출 스택은 의사의 유사한 부분에 링에 속하는 방법이다 :

applyBeanPostProcessorsBeforeInitialization(param)
			throws BeansException {
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessBeforeInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}
复制代码

그것은 루프에서 널 이동합니다되는 빈을 반환하는 방법이있는 경우이 코드는 모든 BeanPostProcessor를 통과함으로써 얻어진다, 다음 하나 하나 postProcessBeforeInitialization에 의해이 방법의 재 작성이 수행되고, 다음 postProcessBeforeInitialization 방법은 실행되지 않습니다. 초기화 방법은 동일 applyBeanPostProcessorsAfterInitialization 후 마찬가지로 실행된다. 포스트 프로세서 콩 초기화 프로세스의 일반적인 개요 (도 2). :

컨테이너 초기화 과정

IOC 컨테이너 말하자면 스프링은 두 개의 인터페이스에서 불가분의 BeanFactory와 ApplicationContext를가되는 BeanFactory의 하위 인터페이스이다의 ApplicationContext는 그들 스프링 컨테이너를 나타낼 수있다. 호출 스택의도 브레이크 포인트에 도시 된 방법은 용기 (AnnotationConfigApplicationContext 예를 얻기 위해 용기)를 초기화하기 위해 수행 된 작업을 분석하는 데 사용될 수있다 :

  • 초기화 : 구성 클래스 등록은 용기를 새로 고침) (새로 고침 전화

  • 새로 고침 과정 :

  • registerBeanPostProcessors (파람)는 빈의 생성을 차단하는 콩 포스트 프로세서 등록

    • 그것은 개체를 만들 필요가 정의한됩니다 BeanPostProcessor
    • BeanPostProcessor가 PriorityOrdered을 구현 구별된다, 주문
    • 일출 PriorityOrdered 인터페이스 BeanPostProcessor 달성
    • 등록 혈관 보내기 BeanPostProcessor 정렬 인터페이스를 달성
    • 마지막으로 등록 인터페이스 BeanPostProcessor의 우선 순위를 구현하지 않았다 (기존 포스트 프로세서)
    • BeanPostProcessor를 등록, 봄이 실제로 컨테이너에 저장 무엇을 만들고, 다음 프로세스가 콩 생성됩니다 예 3 빈 속성 할당에 콩 예를 doCreateBean (파람) 방법 2, populateBean (파람)을 작성, 1, initializeBean (파람) : 초기화 콩 4 invokeAwareMethods () : 콩 인식 5, 사후 처리기 프로세스 콜백 인터페이스를 처리하기위한 방법을 구현 :도 반응식 2.
    • beanFactory.addBeanPostProcessor는 : 컨테이너에 배치 완성 된 BeanPostProcessor를 만들려면

========== 상기 처리가 완료된 등록 BeanPostProcessor 작성

  • 공정 연결 새로 고침 :
  • finishBeanFactoryInitialization (파람)는 BeanFactory가 초기화 작업을 완료하고, 나머지는 빈의 단일 인스턴스를 생성
  • 콩은 단일 인스턴스 메서드 호출 스택을 만든 : getBean-> doGetBean () -> getSingleton () - createBean-doCreateBean 다음 콩을 만들 수 위의 과정을 반복하는 것입니다. 이 섹션에서는 콩이 일시적으로 봄 AspectJ의 소스 코드를 분석 할 때까지, 느린 속도를 늦추고 다시 단계로 doCreateBean하기의 getBean에서 일부 작업이 무엇인지 분석하는 소스 코드를 생성에 대해 자세히 설명합니다.

스프링의 하단 BeanPostProcessor

봄, 콩 인식 인터페이스는 처음 후, 당신은 당신이 기본 Spring 컨테이너의 구성 요소 중 일부를 사용하려면 해당 자원의 일부, 즉, 사용자 정의 구성 요소를 얻을 수에 (ApplicationContext를,의 BeanFactory를, XXX) 다음 사용자 지정 구성 요소 필요성 xxxxAware 인터페이스를 달성하기 위해, 오브젝트를 생성 할 때의 방법은, 그 인터페이스에 지정된 주입 관련 컴포넌트를 호출 빈의 정의에 주입의 일부 구성 요소의 기초가되는 스프링; ApplicationContextAware는 이 인터페이스 전류 관통 할 수있는 스프링 인스턴스 콩을 초기화 할 때 될 스프링 컨텍스트 전달, 즉 스프링 용기 얻어진 실제 현상은 종종 (컨테이너에 대한 접근을 용이하게하는 빈을 취득) 유틸리티 클래스로 패키지 :

//将组件注册添加到容器中后可以直接当作工具类
public class SpringContextTool implements ApplicationContextAware {

    private static ApplicationContext context = null;

    public static Object getBean(String beanName) {
        return context.getBean(beanName);
    }

    public static <T> T getBean(Class<T> clazz){
        return context.getBean(clazz);
    }

    public static ApplicationContext getContext() {
        return context;
    }

    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        context = applicationContext;//打个断点
    }
}
复制代码

작동 원리 : 콩 초기화 메소드 실행 전에 본 메소드 호출 스택 컨테이너를보고, 재정의 방법 중단 점을 명중 postProcessBeforeInitialization 방법 후 처리를 수행 프로그램이 ApplicationContextAwareProcessor 뛰어이 클래스 (클래스는 인터페이스 BeanPostProcessor를 구현 ) postProcessBeforeInitialization 방법 재기록이 수행되고, 현재의 빈 초기화 시간을 결정 점프 invokeAwareInterfaces 방법 상속 대응 인식, 대응하는 세트의 메소드가 호출되는 경우, 해당 자원을 통과.

마찬가지로이 EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware의 예는 아래의 다른 스프링 조립체 EmbeddedValueResolverAware을 주입하고,이 인식 스프링 완전한 인터페이스 속성의 속성 값을 구 파일 달성 될 수있다 :

public class PropertiesUtil implements EmbeddedValueResolverAware {

    private static StringValueResolver resolver;

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = resolver;
    }
    public static String getPropertiesValue(String key) {
        StringBuilder name = new StringBuilder("${").append(key).append("}");
        return resolver.resolveStringValue(name.toString());
    }
}
复制代码

원하는 속성 파일 속성 값을 얻는 경우 그것은 사용될 수있다 : propertiesUtil.getPropertiesValue를 ( "XXXXXXX") 또는 @value ( "XXXX")를 얻을 속성 값을 달성하기 위해. 연주 후 중단 점을 발견하고 ApplicationContextAware 원리는 동일합니다. 현재 초기화 빈이 대응하는 세트의 메소드가 호출되는 경우는, 해당 리소스를 인식 통과 대응 상속 할 때를 판정한다. 소스는 다음과 같이 :

private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}
复制代码

ServletContextAware, ServletConfigAware 및 여러 가지 다른 원리는 거의 비슷합니다. 데이터 검증도 마찬가지로 실현된다 BeanValidationPostProcessor있는 BeanPostProcessor 인터페이스뿐만 InitDestroyAnnotationBeanPostProcessor 또한 주로 JSR250 몇몇 통계를 프로세싱이 인터페이스를 구현 한, AutowiredAnnotationBeanPostProcessor 또한 @Autowired 처리에 대한 인터페이스를 구현 참고 콩을로드. 짧은, 콩 할당에서, 비동기, 라이프 사이클 @, @ autowire가 다른 구성 요소를 주입 등 BeanPostProcessor를 사용하여 수행됩니다. 여기에 사용하고 다시 분석은 다음 장에서와 플로우 차트를 구성하는 몇 가지 원칙이 있습니다.

추천

출처blog.csdn.net/weixin_33797791/article/details/91374715