Spring 탭 을 통 해 외부 프로필 가 져 오기
먼저 프로필 이 외부 프로필 을 어떻게 가 져 오 는 지 볼 까요?spring-import 설정 파일 을 다음 과 같이 정의 합 니 다.
<?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">
<import resource="spring-config.xml"/>
<bean id="innerPerson" class="com.john.aop.Person">
</bean>
</beans>
우 리 는 탭 을 정의 하고 가 져 온 자원 파일 을 spring-config.xml 로 속성 resource 로 설명 하 는 것 을 보 았 습 니 다.spring-config.xml 프로필 이 어떤 지 다시 봅 시다.
<?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">
<bean id="outerPerson" class="com.john.aop.Person">
<property name="firstName" value="john"/>
<property name="lastName" value="wonder"/>
</bean>
<bean id="ChineseFemaleSinger" class="com.john.beanFactory.Singer" abstract="true" >
<property name="country" value=" "/>
<property name="gender" value=" "/>
</bean>
</beans>
그리고 우 리 는 spring-import 이 프로필 을 불 러 오기 위해 BeanFactory 를 실례 화 할 수 있 습 니 다.
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-import.xml");
Person outerPerson=(Person)context.getBean("outerPerson");
System.out.println(outerPerson);
}
만약 문제 가 없다 면,우 리 는 outerPerson 이라는 bean 을 얻 고 인쇄 할 수 있 습 니 다.
Person [0, john wonder]
의 원리스프링 이 import 탭 을 어떻게 분석 하고 가 져 온 프로필 을 불 러 오 는 지 원본 코드 를 통 해 분석 합 니 다.우선 DefaultBean Definition DocumentReader 클래스 에서 보 겠 습 니 다.
DefaultBeanDefinitionDocumentReader
우 리 는 클래스 에서 Public static final 을 정의 하 는 IMPORT 를 볼 수 있 습 니 다.ELEMENT 변수:
public static final String IMPORT_ELEMENT = "import";
그리고 이 변 수 를 사용 한 변 수 를 검색 하고 parseDefaultElement 함수 로 찾 을 수 있 습 니 다.parseDefaultElement
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//todo import 2020-11-17
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
}
이것 이 바로 우리 가 찾 는 외부 프로필 을 가 져 와 Bean 정의 소스 코드 를 불 러 옵 니 다.importBeanDefinitionResource 함 수 를 중점적으로 보 겠 습 니 다.importBeanDefinitionResource
/**
* Parse an "import" element and load the bean definitions
* from the given resource into the bean factory.
*/
protected void importBeanDefinitionResource(Element ele) {
//// resource
String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
//// ,
if (!StringUtils.hasText(location)) {
getReaderContext().error("Resource location must not be empty", ele);
return;
}
// Resolve system properties: e.g. "${user.dir}"
// // , :"${user.dir}"
location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);
Set<Resource> actualResources = new LinkedHashSet<>(4);
// Discover whether the location is an absolute or relative URI
//// location
boolean absoluteLocation = false;
try {
// classpath*: classpath:
absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
}
catch (URISyntaxException ex) {
// cannot convert to an URI, considering the location relative
// unless it is the well-known Spring prefix "classpath*:"
}
// Absolute or relative?
// loadBeanDefinitions
if (absoluteLocation) {
try {
int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
if (logger.isTraceEnabled()) {
logger.trace("Imported " + importCount + " bean definitions from URL location [" + location + "]");
}
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error(
"Failed to import bean definitions from URL location [" + location + "]", ele, ex);
}
}
else {
// , Resource,
// No URL -> considering resource location as relative to the current file.
try {
int importCount;
Resource relativeResource = getReaderContext().getResource().createRelative(location);
// bean
if (relativeResource.exists()) {
importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
actualResources.add(relativeResource);
}
else {
String baseLocation = getReaderContext().getResource().getURL().toString();
//todo import loadBeanDefinitions 2020-10-17
importCount = getReaderContext().getReader().loadBeanDefinitions(
StringUtils.applyRelativePath(baseLocation, location), actualResources);
}
if (logger.isTraceEnabled()) {
logger.trace("Imported " + importCount + " bean definitions from relative location [" + location + "]");
}
}
}
}
이 코드 가 어떤 절차 인지 분석 해 보 겠 습 니 다.1.우선 resource 탭 을 통 해 속성 값 을 분석 하고 문자열 값 이 비어 있 는 지 확인 합 니 다.
2.다음 에 현재 컨 텍스트 환경 을 통 해 문자열 경로 의 자리 표시 자 를 분석 할 것 입 니 다.이 점 은 이전 글 에서 분석 한 적 이 있 습 니 다.
2.다음 에 절대적 인 경로 인지 판단 하고 리 소스 PatternUtils.isUrl(location)||리 소스 Utils.touri(location).isAbsolute()를 호출 합 니 다.판단,중점:classpath*:또는 classpath:시작 을 절대 경로 로 하거나 URI 인 스 턴 스 를 생 성 할 수 있 습 니 다.절대 경로 로 생각 하거나 URI 의 isAbsolute 로 판단 할 수 있 습 니 다.
3.절대 경로 라면 getReader Context().getReader()를 통 해 XmlBeanDefinitionReader 를 가 져 온 다음 loadBeanDefinitions(String location,@Nullable Set
4.절대 경로 가 아니라면 현재 자원 에 대한 경 로 를 만 들 려 고 합 니 다.(이 점 은 매우 중요 합 니 다)이 프로필 에 있 는 BeanDefinitions 를 loadBeanDefinitions 방법 으로 불 러 옵 니 다.여기 서 우리 가 주의해 야 할 세부 사항 이 있 는데,바로 그것 이 왜 자원 의 존재 여 부 를 판단 하려 고 합 니까?존재 한다 면 loadBeanDefinitions(Resource resource)방법 을 직접 호출 하 는 것 입 니 다.즉,하나의 자원 파일 을 불 러 오 는 것 이 분명 합 니 다.방법 설명 과 같이:
/**
* Load bean definitions from the specified XML file.
* @param resource the resource descriptor for the XML file
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
*/
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//load BeanDefinition
return loadBeanDefinitions(new EncodedResource(resource));
}
지정 한 xml 파일 에서 Bean 정 의 를 불 러 옵 니 다.존재 하지 않 는 다 면 절대 경로 와 마찬가지 로 loadBean Definitions(String location,@Nullable Set
/**
* Load bean definitions from the specified resource location.
* <p>The location can also be a location pattern, provided that the
* ResourceLoader of this bean definition reader is a ResourcePatternResolver.
* @param location the resource location, to be loaded with the ResourceLoader
* (or ResourcePatternResolver) of this bean definition reader
* @param actualResources a Set to be filled with the actual Resource objects
* that have been resolved during the loading process( * ). May be {@code null}
* to indicate that the caller is not interested in those Resource objects.
*/
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
이 location 은 지정 한 자원 경로 에서 BeanDefinitions 를 불 러 오 는 것 을 말 합 니 다.총결산
원본 코드 를 통 해 알 수 있 듯 이 외부 에서 프로필 을 가 져 오 는 것 은 하나의 전체 프로필 을 통 해 각 단일 프로필 확장 을 불 러 올 수 있 는 기 회 를 주 는 것 입 니 다.
이상 은 Spring 이
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.