add kownledge ahout mechine learning2
This commit is contained in:
@@ -0,0 +1,659 @@
|
||||
# Java and Spring
|
||||
|
||||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||||
> 分类 ID:`00000000000002` · 排序:1 · 文章数:14
|
||||
|
||||
## 目录
|
||||
|
||||
1. [Springboot AbstractApplicationContext](#springboot-abstractapplicationcontext)
|
||||
2. [Map Set List](#map-set-list)
|
||||
3. [Java8 AQS](#java8-aqs)
|
||||
4. [Java8 Stream](#java8-stream)
|
||||
5. [Spring superinterface](#spring-superinterface)
|
||||
6. [Springboot DefaultSingletonBeanRegistry](#springboot-defaultsingletonbeanregistry)
|
||||
7. [Springboot SpringApplication](#springboot-springapplication)
|
||||
8. [Springboot AbstractBeanFactory](#springboot-abstractbeanfactory)
|
||||
9. [Springboot AbstractAutowireCapableBeanFactory](#springboot-abstractautowirecapablebeanfactory)
|
||||
10. [Springboot AbstractBeanDefinition](#springboot-abstractbeandefinition)
|
||||
11. [Springboot ConfigurationClassPostProcessor](#springboot-configurationclasspostprocessor)
|
||||
12. [Spring ASM](#spring-asm)
|
||||
13. [PostProcessorRegistrationDelegate](#postprocessorregistrationdelegate)
|
||||
14. [Spring Aop](#spring-aop)
|
||||
|
||||
---
|
||||
|
||||
## 1. Springboot AbstractApplicationContext
|
||||
|
||||
<sub>bid: `00000000000003`</sub>
|
||||
|
||||
## AbstractApplicationContext
|
||||
|
||||
AbstractApplicationContext 是 SpringBoot的 核心应用上下文父类。
|
||||
|
||||
## x.1 properties
|
||||
|
||||
### beanFactoryPostProcessors
|
||||
|
||||
### environment
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### refresh
|
||||
|
||||
refresh 是 Springboot启动中核心方法。
|
||||
|
||||
- prepareRefresh
|
||||
- obtainFreshBeanFactory
|
||||
- prepareBeanFactory
|
||||
- postProcessBeanFactory
|
||||
- invokeBeanFactoryPostProcessors
|
||||
- registerBeanPostProcessors
|
||||
- onRefresh
|
||||
- finishBeanFactoryInitialization
|
||||
- finishRefresh
|
||||
|
||||
---
|
||||
|
||||
## 2. Map Set List
|
||||
|
||||
<sub>bid: `2022051816085000000000000006`</sub>
|
||||
|
||||
### 1. Summary
|
||||
|
||||
我们在开发过程在,最常见的三种数据存储结构就是 Map Set 和List了
|
||||
|
||||
这三种结构最明显的特征就是Map 是键值,Set是对象存储唯一,List是有序数组
|
||||
|
||||
|
||||
### Map<K, V>
|
||||
|
||||
键值存储,主键不允许重复
|
||||
|
||||
添加元素 使用put方法,如果key重复,则value被覆盖
|
||||
|
||||
### Set<E>
|
||||
|
||||
对象存储,对象不允许重复
|
||||
|
||||
/**
|
||||
* if this set did not already contain the specified element will return {@code true}
|
||||
* f this set already contains the element, the call leaves the set
|
||||
* unchanged and returns {@code false}
|
||||
*/
|
||||
public boolean add(E e)
|
||||
|
||||
### List<E>
|
||||
|
||||
list是由数组构成的,这就意味着,list是有顺序的,因为数组在内存中是一段连续的内存。
|
||||
|
||||
---
|
||||
|
||||
## 3. Java8 AQS
|
||||
|
||||
<sub>bid: `2022052314143400000000000014`</sub>
|
||||
|
||||
## AQ
|
||||
|
||||
---
|
||||
|
||||
## 4. Java8 Stream
|
||||
|
||||
<sub>bid: `2022060810550500000000000022`</sub>
|
||||
|
||||
## S
|
||||
|
||||
---
|
||||
|
||||
## 5. Spring superinterface
|
||||
|
||||
<sub>bid: `2022120915183100000000000001`</sub>
|
||||
|
||||
## summary
|
||||
|
||||
|
||||
## 1. Aware(感知)
|
||||
|
||||
Spring Ioc 是解耦行为,我们的业务代码其实是没有感知或者意识到spring框架的存在。如果我们需要使用spring Ioc中的资源时候,我们就需要有意识的去获取这个资源,而Aware 就是这样的存在。
|
||||
|
||||
@Service
|
||||
public class AppContextAware implements ApplicationContextAware {
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext=applicationContext;
|
||||
}
|
||||
|
||||
public void hello(){
|
||||
//user为容器中存在的bean
|
||||
User user = applicationContext.getBean("user", User.class);
|
||||
System.out.println(user);
|
||||
|
||||
//获取容器的环境、User.name为设置好的属性
|
||||
Environment environment = applicationContext.getEnvironment();
|
||||
String property = environment.getProperty("User.name");
|
||||
System.out.println(" 属性:"+property);
|
||||
}
|
||||
}
|
||||
|
||||
一些常用的Aware interface
|
||||
BeanNameAware
|
||||
ApplicationContextAware
|
||||
ResourceLoaderAware
|
||||
EnvironmentAware
|
||||
|
||||
|
||||
|
||||
## 2. BeanFactory
|
||||
|
||||
BeanFactory 提供了获取bean和判断bean的方法,包括
|
||||
|
||||
getBean(String beanName)
|
||||
getBean(String beanName, Class<T> requiredType)
|
||||
getBean(Class<T> requiredType)
|
||||
containsBean(String name)
|
||||
isSingleton(String name)
|
||||
isPrototype(String name)
|
||||
sTypeMatch(String name)
|
||||
getType(String name)
|
||||
String[] getAliases(String name);
|
||||
|
||||
## 3. BeanPostProcessor
|
||||
|
||||
## 4. BeanFactoryPostProcessor
|
||||
|
||||
## 5. ApplicationContext
|
||||
|
||||
## 6. InitializingBean
|
||||
|
||||
---
|
||||
|
||||
## 6. Springboot DefaultSingletonBeanRegistry
|
||||
|
||||
<sub>bid: `2022121513519200000000000002`</sub>
|
||||
|
||||
## DefaultSingletonBeanRegistry
|
||||
|
||||
DefaultSingletonBeanRegistry 是Springboot bean 自动装配的核心实现类。
|
||||
顾名思义,是默认的单例bean 注册器。
|
||||
|
||||
## x.1 properties
|
||||
|
||||
### dependentBeanMap
|
||||
|
||||
存放(依赖对象key -> 被依赖Set)的 ConcurrentHashMap
|
||||
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
|
||||
|
||||
### dependenciesForBeanMap
|
||||
|
||||
存放(被依赖对象key -> 依赖Set)的 ConcurrentHashMap
|
||||
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
|
||||
###
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### registerDependentBean
|
||||
|
||||
我们知道Spring DI 依赖注入,此方法就是依赖注入的核心组成。注意,这段逻辑是加锁的,即存在并行处理逻辑。
|
||||
Springboot 在 AbstractApplicationContext 进行 refresh 操作时候,在最后一步会实例化bean,参照AbstractApplicationContext.finishBeanFactoryInitialization 方法,此方法的流程我们会在xxx讲解。源码如下
|
||||
|
||||
|
||||
/**
|
||||
* Register a dependent bean for the given bean。
|
||||
*/
|
||||
public void registerDependentBean(String beanName, String dependentBeanName) {
|
||||
String canonicalName = canonicalName(beanName);
|
||||
synchronized (this.dependentBeanMap) {
|
||||
Set<String> dependentBeans =
|
||||
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
|
||||
if (!dependentBeans.add(dependentBeanName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (this.dependenciesForBeanMap) {
|
||||
Set<String> dependenciesForBean =
|
||||
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
|
||||
dependenciesForBean.add(canonicalName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DI 在此处的实现逻辑可以通过下面例子来通俗说明:
|
||||
① A对象 依赖 B对象
|
||||
② A对象 依赖 C对象
|
||||
③ D对象 依赖 B对象
|
||||
所以 必须要提前先把 B 对象和 C对象进行实例化后,才能 创建A对象和 D对象。
|
||||
我们从RootBeanDefinition中获取 dependsOn的数组,遍历调用registerDependentBean方法
|
||||
参数beanName是依赖对象,即 B 或者 C,参数dependentBeanName是被依赖对象A
|
||||
1. 传入参数是 (B,A) 时,为 B 创建一个 LinkedHashSet,并在该Set中存放A, 并把 B -> Set的映射关系放入dependentBeanMap中。
|
||||
紧接着 为 A 创建一个 LinkedHashSet, 并在该Set中存放B,并把 A -> Set的映射关系放入dependenciesForBeanMap中。
|
||||
2. 传入参数是 (C, A) 时,为 C 创建一个 LinkedHashSet,并在该Set中存放A, 并把 C -> Set的映射关系放入dependentBeanMap中。
|
||||
因为 dependenciesForBeanMap 已经存在了 A -> Set这个映射,我们只需将 C 也存入这个Set就可以。
|
||||
3. 传入参数是 (B, D) 时,因为 dependentBeanMap 已经存在了 B -> Set这个映射,我们只需将 D 也存入这个Set就可以。
|
||||
紧接着 为 D 创建一个 LinkedHashSet, 并在该Set中存放B,并把 D -> Set的映射关系放入dependenciesForBeanMap中。
|
||||
|
||||
`注意` 依赖和被依赖总是成对出现的,dependentBeans.add(dependentBeanName) 返回 false,视为添加失败,即视为已经存在,根据 依赖和被依赖总是成对出现的,所以后面dependenciesForBean.add(canonicalName) 这部分就没必要执行了,因为执行了也没有意义,所以直接 return了。毕竟dependenciesForBean中已经存在了canonicalName。
|
||||
|
||||
---
|
||||
|
||||
## 7. Springboot SpringApplication
|
||||
|
||||
<sub>bid: `2022121513597200000000000003`</sub>
|
||||
|
||||
## SpringApplication
|
||||
|
||||
## x.1 properties
|
||||
|
||||
### sources
|
||||
|
||||
### environment
|
||||
|
||||
### webApplicationType
|
||||
|
||||
###
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### run
|
||||
|
||||
1. 创建 DefaultBootstrapContext
|
||||
2. 获取 SpringApplicationRunListeners
|
||||
3. 转换 ApplicationArguments 将commandLine args
|
||||
4. 装备环境 ConfigurableEnvironment
|
||||
5. 配置忽略bean情报 configureIgnoreBeanInfo
|
||||
6. 创建 ApplicationContext
|
||||
7. 准备 ApplicationContext prepareContext
|
||||
设置上下文环境,加载source
|
||||
8. 刷新 ApplicationContext
|
||||
9. 刷新后处理
|
||||
|
||||
---
|
||||
|
||||
## 8. Springboot AbstractBeanFactory
|
||||
|
||||
<sub>bid: `2022121515315000000000000004`</sub>
|
||||
|
||||
## AbstractBeanFactory
|
||||
|
||||
|
||||
## x.2 methods
|
||||
|
||||
### doGetBean
|
||||
AbstractBeanFactory 的核心方法 doGetBean,doGetBean方法是由getBean调用的,如果有dependsOn存在,就会将注册依赖, 然调用getBean(dep),从而形成了递归操作。
|
||||
当不存dependsOn的时候mbd.isSingleton 时候,就会调用 getSingleton方法,子类会回调createBean(beanName, mbd, args)方法,去创建bean。
|
||||
|
||||
源码
|
||||
|
||||
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType) {
|
||||
String beanName = transformedBeanName(name);
|
||||
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
|
||||
checkMergedBeanDefinition(mbd, beanName, args);
|
||||
|
||||
// Guarantee initialization of beans that the current bean depends on.
|
||||
String[] dependsOn = mbd.getDependsOn();
|
||||
if (dependsOn != null) {
|
||||
for (String dep : dependsOn) {
|
||||
if (isDependent(beanName, dep)) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
|
||||
}
|
||||
registerDependentBean(dep, beanName);
|
||||
try {
|
||||
getBean(dep);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create bean instance.
|
||||
if (mbd.isSingleton()) {
|
||||
sharedInstance = getSingleton(beanName, () -> {
|
||||
try {
|
||||
return createBean(beanName, mbd, args);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
// Explicitly remove instance from singleton cache: It might have been put there
|
||||
// eagerly by the creation process, to allow for circular reference resolution.
|
||||
// Also remove any beans that received a temporary reference to the bean.
|
||||
destroySingleton(beanName);
|
||||
throw ex;
|
||||
}
|
||||
});
|
||||
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 9. Springboot AbstractAutowireCapableBeanFactory
|
||||
|
||||
<sub>bid: `2022121523309700000000000005`</sub>
|
||||
|
||||
## AbstractAutowireCapableBeanFactory
|
||||
|
||||
父类是AbstractBeanFactory,实现了AutowireCapableBeanFactory 的方法,其中最主要的还是createBean方法。
|
||||
源码
|
||||
|
||||
/**
|
||||
* Central method of this class: creates a bean instance,
|
||||
* populates the bean instance, applies post-processors, etc.
|
||||
* @see #doCreateBean
|
||||
*/
|
||||
@Override
|
||||
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
|
||||
throws BeanCreationException {
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
RootBeanDefinition mbdToUse = mbd;
|
||||
|
||||
// Make sure bean class is actually resolved at this point, and
|
||||
// clone the bean definition in case of a dynamically resolved Class
|
||||
// which cannot be stored in the shared merged bean definition.
|
||||
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
|
||||
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
|
||||
mbdToUse = new RootBeanDefinition(mbd);
|
||||
mbdToUse.setBeanClass(resolvedClass);
|
||||
}
|
||||
|
||||
// Prepare method overrides.
|
||||
try {
|
||||
mbdToUse.prepareMethodOverrides();
|
||||
}
|
||||
catch (BeanDefinitionValidationException ex) {
|
||||
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
|
||||
beanName, "Validation of method overrides failed", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
|
||||
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
|
||||
if (bean != null) {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
|
||||
"BeanPostProcessor before instantiation of bean failed", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Finished creating instance of bean '" + beanName + "'");
|
||||
}
|
||||
return beanInstance;
|
||||
}
|
||||
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
|
||||
// A previously detected exception with proper bean creation context already,
|
||||
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
|
||||
throw ex;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(
|
||||
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 10. Springboot AbstractBeanDefinition
|
||||
|
||||
<sub>bid: `2022121523361800000000000006`</sub>
|
||||
|
||||
## AbstractBeanDefinition
|
||||
|
||||
AbstractBeanDefinition 定义了 一个bean的各种描述。
|
||||
|
||||
## x.1
|
||||
|
||||
### String[] dependsOn
|
||||
|
||||
### Resource resource
|
||||
|
||||
###
|
||||
|
||||
---
|
||||
|
||||
## 11. Springboot ConfigurationClassPostProcessor
|
||||
|
||||
<sub>bid: `2022121612282000000000000009`</sub>
|
||||
|
||||
## ConfigurationClassPostProcessor
|
||||
|
||||
这一节主要讲的是ConfigurationClassPostProcessor和他的一些生态。
|
||||
他的生态有
|
||||
- ConfigurationClassParser 真正的处理者。
|
||||
- ComponentScanAnnotationParser 扫描classpath,把beanName加入到registry的beanDefinitionMap中。
|
||||
- doProcessConfigurationClass 是该 postProcessor最核心的处理方法
|
||||
|
||||
/**
|
||||
* Apply processing and build a complete {@link ConfigurationClass} by reading the
|
||||
* annotations, members and methods from the source class. This method can be called
|
||||
* multiple times as relevant sources are discovered.
|
||||
* @param configClass the configuration class being build
|
||||
* @param sourceClass a source class
|
||||
* @return the superclass, or {@code null} if none found or previously processed
|
||||
*/
|
||||
@Nullable
|
||||
protected final SourceClass doProcessConfigurationClass(
|
||||
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
|
||||
throws IOException {
|
||||
|
||||
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
|
||||
// Recursively process any member (nested) classes first
|
||||
processMemberClasses(configClass, sourceClass, filter);
|
||||
}
|
||||
// Process any @PropertySource annotations
|
||||
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
|
||||
sourceClass.getMetadata(), PropertySources.class,
|
||||
org.springframework.context.annotation.PropertySource.class)) {
|
||||
if (this.environment instanceof ConfigurableEnvironment) {
|
||||
processPropertySource(propertySource);
|
||||
}
|
||||
else {
|
||||
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
|
||||
"]. Reason: Environment must implement ConfigurableEnvironment");
|
||||
}
|
||||
}
|
||||
// Process any @ComponentScan annotations
|
||||
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
|
||||
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
|
||||
if (!componentScans.isEmpty() &&
|
||||
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
|
||||
for (AnnotationAttributes componentScan : componentScans) {
|
||||
// The config class is annotated with @ComponentScan -> perform the scan immediately
|
||||
Set<BeanDefinitionHolder> scannedBeanDefinitions =
|
||||
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
|
||||
// Check the set of scanned definitions for any further config classes and parse recursively if needed
|
||||
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
|
||||
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
|
||||
if (bdCand == null) {
|
||||
bdCand = holder.getBeanDefinition();
|
||||
}
|
||||
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
|
||||
parse(bdCand.getBeanClassName(), holder.getBeanName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process any @Import annotations
|
||||
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
|
||||
|
||||
// Process any @ImportResource annotations
|
||||
AnnotationAttributes importResource =
|
||||
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
|
||||
if (importResource != null) {
|
||||
String[] resources = importResource.getStringArray("locations");
|
||||
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
|
||||
for (String resource : resources) {
|
||||
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
|
||||
configClass.addImportedResource(resolvedResource, readerClass);
|
||||
}
|
||||
}
|
||||
|
||||
// Process individual @Bean methods
|
||||
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
|
||||
for (MethodMetadata methodMetadata : beanMethods) {
|
||||
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
|
||||
}
|
||||
|
||||
// Process default methods on interfaces
|
||||
processInterfaces(configClass, sourceClass);
|
||||
|
||||
// Process superclass, if any
|
||||
if (sourceClass.getMetadata().hasSuperClass()) {
|
||||
String superclass = sourceClass.getMetadata().getSuperClassName();
|
||||
if (superclass != null && !superclass.startsWith("java") &&
|
||||
!this.knownSuperclasses.containsKey(superclass)) {
|
||||
this.knownSuperclasses.put(superclass, configClass);
|
||||
// Superclass found, return its annotation metadata and recurse
|
||||
return sourceClass.getSuperClass();
|
||||
}
|
||||
}
|
||||
|
||||
// No superclass -> processing is complete
|
||||
return null;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
## 12. Spring ASM
|
||||
|
||||
<sub>bid: `2022121615335100000000000010`</sub>
|
||||
|
||||
## asm
|
||||
|
||||
在spring中其实很少听到asm这个关键字,asm -> Assembly,跟多是指汇编语言。
|
||||
|
||||
spring也是用到asm,而且asm包是spring-core的组成部分。spring asm 大体上跟 原生的asm 都是差不多了。
|
||||
|
||||
(参照链接)[ https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/asm/package-summary.htm ]
|
||||
|
||||
|
||||
package org.springframework.asm
|
||||
Spring's repackaging of ASM 9.x (with Spring-specific patches; for internal use only).
|
||||
This repackaging technique avoids any potential conflicts with dependencies on ASM at the application level or from third-party libraries and frameworks.
|
||||
|
||||
As this repackaging happens at the class file level, sources and javadocs are not available here.
|
||||
|
||||
从package-info可以看出,repackaging,avoids any potential conflicts
|
||||
|
||||
---
|
||||
|
||||
## 13. PostProcessorRegistrationDelegate
|
||||
|
||||
<sub>bid: `2022121915527600000000000011`</sub>
|
||||
|
||||
## PostProcessorRegistrationDelegate
|
||||
|
||||
作为 Delegate 提供了 静态方法 invokeBeanFactoryPostProcessors。
|
||||
|
||||
主要是将beanFactory和beanFactoryPostProcessors做matching,
|
||||
然后对beanFactoryPostProcessors做遍历调用postProcessBeanFactory(beanFactory)
|
||||
|
||||
## ConfigurationClassPostProcessor
|
||||
|
||||
postProcessBeanFactory(beanFactory)
|
||||
|
||||
processConfigBeanDefinitions(beanFactory)
|
||||
|
||||
核心的 处理方法,
|
||||
|
||||
---
|
||||
|
||||
## 14. Spring Aop
|
||||
|
||||
<sub>bid: `2022122715594900000000000012`</sub>
|
||||
|
||||
## Aop
|
||||
Aspect Oriented Programming的缩写,意为:面向切面编程。
|
||||
Spring aop 作为spring的一个模块,在springboot中是在bean的实例化中使用的。
|
||||
|
||||
AbstractAutowireCapableBeanFactory#initializeBean
|
||||
|
||||
|
||||
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
# 实现了Aware接口<BeanNameAware><BeanClassLoaderAware><BeanFactoryAware>会invoke对应的set方法。
|
||||
invokeAwareMethods(beanName, bean);
|
||||
}
|
||||
|
||||
Object wrappedBean = bean;
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
# beanPostProcesser的before方法。
|
||||
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
|
||||
}
|
||||
|
||||
try {
|
||||
# 实现了InitializingBean接口的会invoke afterPropertiesSet方法。
|
||||
invokeInitMethods(beanName, wrappedBean, mbd);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(
|
||||
(mbd != null ? mbd.getResourceDescription() : null),
|
||||
beanName, "Invocation of init method failed", ex);
|
||||
}
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
# beanPostProcesser的after方法。
|
||||
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
|
||||
}
|
||||
|
||||
return wrappedBean;
|
||||
}
|
||||
|
||||
AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
|
||||
// Ignore AOP infrastructure such as scoped proxies.
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (bean instanceof Advised) {
|
||||
Advised advised = (Advised) bean;
|
||||
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
|
||||
// Add our local Advisor to the existing proxy's Advisor chain...
|
||||
if (this.beforeExistingAdvisors) {
|
||||
advised.addAdvisor(0, this.advisor);
|
||||
}
|
||||
else {
|
||||
advised.addAdvisor(this.advisor);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEligible(bean, beanName)) {
|
||||
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
|
||||
if (!proxyFactory.isProxyTargetClass()) {
|
||||
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
|
||||
}
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
customizeProxyFactory(proxyFactory);
|
||||
|
||||
// Use original ClassLoader if bean class not locally loaded in overriding class loader
|
||||
ClassLoader classLoader = getProxyClassLoader();
|
||||
if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {
|
||||
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
|
||||
}
|
||||
# ProxyFactory 其实就是创建动态代理或者Cglib的 InvocationHandler调用Proxy.newProxyInstance返回代理对象
|
||||
return proxyFactory.getProxy(classLoader);
|
||||
}
|
||||
|
||||
// No proxy needed.
|
||||
return bean;
|
||||
}
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user