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】