1. 程式人生 > 其它 >Springboot漫遊日誌(32)

Springboot漫遊日誌(32)

技術標籤:學習springjavaspring boot後端

Springboot漫遊日誌(32)

遺留:【Binder】【logback日誌】【載入properties或者yml】【解析環境變數key】【PathMatchingResourcePatternResolver】
【ClassPathBeanDefinitionScanner】

現在看【AnnotatedBeanDefinitionReader】—》【AnnotationConfigUtils】的方法【registerAnnotationConfigProcessors】的165行

Set<BeanDefinitionHolder>
beanDefs = new LinkedHashSet<>(8); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)
); }

建立【RootBeanDefinition】這一行已經看了。
接著看下面的。

source是從過載的方法傳入的,是null。

/**
 * Register all relevant annotation post processors in the given registry.
 * @param registry the registry to operate on
 */
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors
(registry, null); }

這個null被賦值給了【RootBeanDefinition 】的父類方法【BeanMetadataAttributeAccessor】的屬性【source】

@Nullable
private Object source;
/**
 * Set the configuration source {@code Object} for this metadata element.
 * <p>The exact type of the object will depend on the configuration mechanism used.
 */
public void setSource(@Nullable Object source) {
	this.source = source;
}

沒啥說的。

接著看【registerPostProcessor】方法。

private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}

三個引數很好理解。
registry是【AnnotationConfigServletWebServerApplicationContext】,他是一個applicationContext。
definition是剛創建出來熱騰騰的【RootBeanDefinition 】
beanName是一個字串常量,值為【org.springframework.context.annotation.internalConfigurationAnnotationProcessor】

第一行的方法,點進去

/**
 * Set the role hint for this {@code BeanDefinition}.
 */
@Override
public void setRole(int role) {
	this.role = role;
}

【BeanDefinition.ROLE_INFRASTRUCTURE】是介面【BeanDefinition】中定義的一個常量int,值為2.
這個常量有註釋,這裡就不看了。

this.role是【AbstractBeanDefinition】的一個例項屬性,初始值是【BeanDefinition.ROLE_APPLICATION】,也是一個常量,值是0.

接著看。

registry.registerBeanDefinition(beanName, definition);

registry是一個applicationContext,所以他呼叫的是【GenericApplicationContext】的【registerBeanDefinition】方法。

//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry
//---------------------------------------------------------------------

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}

接著到【DefaultListableBeanFactory】,這是一個長長的方法,有一百行。

//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//---------------------------------------------------------------------

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	Assert.hasText(beanName, "Bean name must not be empty");
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");

	if (beanDefinition instanceof AbstractBeanDefinition) {
		try {
			((AbstractBeanDefinition) beanDefinition).validate();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Validation of bean definition failed", ex);
		}
	}

	BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
	if (existingDefinition != null) {
		if (!isAllowBeanDefinitionOverriding()) {
			throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
		}
		else if (existingDefinition.getRole() < beanDefinition.getRole()) {
			// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
			if (logger.isInfoEnabled()) {
				logger.info("Overriding user-defined bean definition for bean '" + beanName +
						"' with a framework-generated bean definition: replacing [" +
						existingDefinition + "] with [" + beanDefinition + "]");
			}
		}
		else if (!beanDefinition.equals(existingDefinition)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Overriding bean definition for bean '" + beanName +
						"' with a different definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Overriding bean definition for bean '" + beanName +
						"' with an equivalent definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		this.beanDefinitionMap.put(beanName, beanDefinition);
	}
	else {
		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			synchronized (this.beanDefinitionMap) {
				this.beanDefinitionMap.put(beanName, beanDefinition);
				List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
				updatedDefinitions.addAll(this.beanDefinitionNames);
				updatedDefinitions.add(beanName);
				this.beanDefinitionNames = updatedDefinitions;
				removeManualSingletonName(beanName);
			}
		}
		else {
			// Still in startup registration phase
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			removeManualSingletonName(beanName);
		}
		this.frozenBeanDefinitionNames = null;
	}

	if (existingDefinition != null || containsSingleton(beanName)) {
		resetBeanDefinition(beanName);
	}
	else if (isConfigurationFrozen()) {
		clearByTypeCache();
	}
}

看第一個if條件,進入【AbstractBeanDefinition】

private MethodOverrides methodOverrides = new MethodOverrides();
@Nullable
private String factoryMethodName;
/**
 * Validate this bean definition.
 * @throws BeanDefinitionValidationException in case of validation failure
 */
public void validate() throws BeanDefinitionValidationException {
	if (hasMethodOverrides() && getFactoryMethodName() != null) {
		throw new BeanDefinitionValidationException(
				"Cannot combine factory method with container-generated method overrides: " +
				"the factory method must create the concrete bean instance.");
	}
	if (hasBeanClass()) {
		prepareMethodOverrides();
	}
}
/**
 * Return if there are method overrides defined for this bean.
 * @since 5.0.2
 */
public boolean hasMethodOverrides() {
	return !this.methodOverrides.isEmpty();
}
/**
 * Return a factory method, if any.
 */
@Override
@Nullable
public String getFactoryMethodName() {
	return this.factoryMethodName;
}
/**
 * Return whether this definition specifies a bean class.
 * @see #getBeanClass()
 * @see #setBeanClass(Class)
 * @see #resolveBeanClass(ClassLoader)
 */
public boolean hasBeanClass() {
	return (this.beanClass instanceof Class);
}
/**
 * Validate and prepare the method overrides defined for this bean.
 * Checks for existence of a method with the specified name.
 * @throws BeanDefinitionValidationException in case of validation failure
 */
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
	// Check that lookup methods exist and determine their overloaded status.
	if (hasMethodOverrides()) {
		getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
	}
}

在【RootBeanDefinition 】例項化的時候,很多都是預設值
【hasMethodOverrides】返回false
【factoryMethodName】是null
【hasBeanClass】返回true。beanClass 值為【ConfigurationClassPostProcessor.class】。

所以這個方法啥也不做。

回到【DefaultListableBeanFactory】的942行。

BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

【RootBeanDefinition 】例項化的時候,【beanDefinitionMap】只是一個空集合。
所以得到的【existingDefinition 】是null。
走else裡面的邏輯。

/** Names of beans that have already been created at least once. */
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
/**
 * Check whether this factory's bean creation phase already started,
 * i.e. whether any bean has been marked as created in the meantime.
 * @since 4.2.2
 * @see #markBeanAsCreated
 */
protected boolean hasBeanCreationStarted() {
	return !this.alreadyCreated.isEmpty();
}

這個仍然是空的,所以走下面的邏輯。

// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);

在這裡,一個bean定義被儲存下來了,bean名稱也被放到一個集合中。

private void removeManualSingletonName(String beanName) {
	updateManualSingletonNames(set -> set.remove(beanName), set -> set.contains(beanName));
}

/**
 * Update the factory's internal set of manual singleton names.
 * @param action the modification action
 * @param condition a precondition for the modification action
 * (if this condition does not apply, the action can be skipped)
 */
private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
	if (hasBeanCreationStarted()) {
		// Cannot modify startup-time collection elements anymore (for stable iteration)
		synchronized (this.beanDefinitionMap) {
			if (condition.test(this.manualSingletonNames)) {
				Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
				action.accept(updatedSingletons);
				this.manualSingletonNames = updatedSingletons;
			}
		}
	}
	else {
		// Still in startup registration phase
		if (condition.test(this.manualSingletonNames)) {
			action.accept(this.manualSingletonNames);
		}
	}
}

removeManualSingletonName也不難理解。

hasBeanCreationStarted之前就看了,是false。
所以走else邏輯。

private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

如果【manualSingletonNames 】中包含bean名稱,就把他移除了。

回到之前的方法,【frozenBeanDefinitionNames】被設定為null。

往下看。

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
@Override
public boolean containsSingleton(String beanName) {
	return this.singletonObjects.containsKey(beanName);
}

【singletonObjects】如果裡面包含bean名稱,呼叫【resetBeanDefinition】
【resetBeanDefinition】方法不短,這裡不走這個邏輯,就不看了。

/** Whether bean definition metadata may be cached for all beans. */
private volatile boolean configurationFrozen;
@Override
public boolean isConfigurationFrozen() {
	return this.configurationFrozen;
}

這裡也是false,那【registerBeanDefinition】方法就走完了。

返回到【AnnotationConfigUtils】的【registerPostProcessor】方法。

private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}

看return。

【BeanDefinitionHolder】沒有父類。

private final BeanDefinition beanDefinition;

private final String beanName;

@Nullable
private final String[] aliases;
/**
 * Create a new BeanDefinitionHolder.
 * @param beanDefinition the BeanDefinition to wrap
 * @param beanName the name of the bean, as specified for the bean definition
 */
public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
	this(beanDefinition, beanName, null);
}

/**
 * Create a new BeanDefinitionHolder.
 * @param beanDefinition the BeanDefinition to wrap
 * @param beanName the name of the bean, as specified for the bean definition
 * @param aliases alias names for the bean, or {@code null} if none
 */
public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) {
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");
	Assert.notNull(beanName, "Bean name must not be null");
	this.beanDefinition = beanDefinition;
	this.beanName = beanName;
	this.aliases = aliases;
}

給三個例項屬性賦值
aliases是null,看註釋,這是bean的別名。

然後【registerPostProcessor】也看完了。

還是這個類【AnnotationConfigUtils】,回到【registerAnnotationConfigProcessors】方法。

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
	RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

執行if裡面的最後一行,把得到的【BeanDefinitionHolder】例項,新增到beanDefs集合。

接著後面全是同樣的程式碼,我在想,為啥不抽象成方法
難道像我們一樣,加班太嚴重了。笑

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
	RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
	RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
	RootBeanDefinition def = new RootBeanDefinition();
	try {
		def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
				AnnotationConfigUtils.class.getClassLoader()));
	}
	catch (ClassNotFoundException ex) {
		throw new IllegalStateException(
				"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
	}
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
	RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
	RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}

列一下其餘這個常量的值

/**
 * The bean name of the internally managed Autowired annotation processor.
 */
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
		"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
/**
 * The bean name of the internally managed JSR-250 annotation processor.
 */
public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
		"org.springframework.context.annotation.internalCommonAnnotationProcessor";
/**
 * The bean name of the internally managed JPA annotation processor.
 */
public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
		"org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
/**
 * The bean name of the internally managed @EventListener annotation processor.
 */
public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
		"org.springframework.context.event.internalEventListenerProcessor";
/**
 * The bean name of the internally managed EventListenerFactory.
 */
public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
		"org.springframework.context.event.internalEventListenerFactory";

對應的class依次為

  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
  • EventListenerMethodProcessor
  • DefaultEventListenerFactory

其中【COMMON_ANNOTATION_PROCESSOR_BEAN_NAME】對應的class【CommonAnnotationBeanPostProcessor】,只有在【jsr250Present】為true是才載入。

private static final boolean jsr250Present;

private static final boolean jpaPresent;

static {
	ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader();
	jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", classLoader);
	jpaPresent = ClassUtils.isPresent("javax.persistence.EntityManagerFactory", classLoader) &&
			ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader);
}

jsr250看的是類路徑中是否有【javax.annotation.Resource】
jpaPresent 看的是類路徑中是否有【javax.persistence.EntityManagerFactory】和【org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor】

就是Resource註解,和JPA。

最後把集合返回

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

到這裡【AnnotationConfigUtils】的【registerAnnotationConfigProcessors】就執行完了。

然後【AnnotatedBeanDefinitionReader】的例項化也就完成了。


遺留:【Binder】【logback日誌】【載入properties或者yml】【解析環境變數key】【PathMatchingResourcePatternResolver】
【ClassPathBeanDefinitionScanner】

現在看【AnnotatedBeanDefinitionReader】—》【AnnotationConfigUtils】的方法【registerAnnotationConfigProcessors】

下次看:【ClassPathBeanDefinitionScanner】