site oficial da Primavera leia as séries (X): Primavera de feijão no ciclo de vida (inferior)

 

site oficial da Primavera ler a série (nove): Spring Bean no ciclo de vida (inferior)

 

O artigo anterior, temos que o ciclo de vida do feijão de fazer uma breve introdução, descreve a fase de inicialização do ciclo de vida e o mecanismo de retorno de chamada de início e paragem de recipiente com base LifeCycleBean, para além do processo de destruição do feijão também feita uma breve introdução . Mas feijão para todo o ciclo de vida, isto é apenas uma pequena parte, neste artigo, vamos aprender a completar a parte restante do estudo, enquanto os conteúdos anteriores fazer um comentário. ciclo de vida inteiro do feijão, de acordo com a nossa apresentação anterior, pode ser dividido em quatro partes

Exemplos de atributo injecção destruição inicialização

Este artigo descreve a fase de injecção e atributos instanciado

conceito Ciclo de Vida de complementaridade

Embora sempre dissemos toda feijão ciclo de vida é dividido em quatro partes, mas acredito que muitos estudantes têm sido, no final, por onde começar para o ciclo de vida do Bean, onde o fim não é um conceito claro. Pode-se dizer, não que instanciado a partir do início ao fim para o destruir? Claro, isso não é errado, mas exatamente quando os operadores começam a instanciar isso? Quando eles contam destruí-lo? A questão de saber se você pode ou não responder a isso claramente? Se não, por favor, continue a ler.

Eu acredito que todo o Spring Bean no ciclo de vida, desde o primeiro postprocessor chamada de método applyBeanPostProcessorsBeforeInstantiation no início, este método tem a intenção de ver para saber o nome, o que se traduz para chamar postprocessor antes instanciado. O método chamada applyBeanPostProcessorsAfterInitialization, a fase final do meio do ciclo de vida do feijão que foi criado. Para a destruição de nenhuma ambigüidade, isto é, chamar os métodos correspondentes de destruição Bean poderia pensar que, com esta vida chegou ao fim, marcando o fim do ciclo de vida Bean. Em seguida, combinado com as conclusões do artigo anterior, eu agora variam ciclo de vida do feijão definidos da seguinte forma:

site oficial da Primavera ler a série (nove): Spring Bean no ciclo de vida (inferior)

 

Note-se que, para a digitalização BeanDefinion, análise, validação não faz parte do ciclo de vida do Bean. Tal definição clara do conceito de ciclo de vida Bean é necessário, talvez apenas começando para nós, ciclo de vida do feijão é uma bagunça, mas pelo menos agora temos apanhado fio. Feijão, enquanto todo o ciclo de vida, vou ser dividido em duas partes

  • criar
  • destruir

Para o período de destruição, não precisamos de muita atenção, para a fase de criação, sinais começaram a se comportar como: applyBeanPostProcessorsBeforeInstantiation método de execução, marcou o fim de comportamento: Método applyBeanPostProcessorsAfterInitialization é executado.

Com base na conclusão acima, vamos começar a próxima análise para análise de código neste artigo, consulte a tabela seguinte

site oficial da Primavera ler a série (nove): Spring Bean no ciclo de vida (inferior)

 

instanciação

Exemplos de todo o processo para a imagem principal acima 3-11-6-4 (createBean) e 3-11-6-4-1 Passo (doCreateBean)

análise processo createBean

Código é a seguinte:

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

RootBeanDefinition mbdToUse = mbd;

// 第一步:解析BeanDefinition中的beanClass属性
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

try {
// 第二步:处理lookup-method跟replace-method,判断是否存在方法的重载
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try {
// 第三步:判断这个类在之后是否需要进行AOP代理
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 {
// 开始创建Bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}

Pode ser visto, com o primeiro passo ou o segundo passo no processo de fazer BeanDefinition alguma da propriedade, que não faz parte do nosso ciclo de vida de Bean, que pular, então olhar para a terceira etapa do código:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 不是合成类,并且有实例化后置处理器。这个判断基本上恒成立
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 获取这个BeanDefinition的类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 这里执行的主要是AbstractAutoProxyCreator这个类中的方法,决定是否要进行AOP代理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 这里执行了一个短路操作,如果在这个后置处理中直接返回了一个Bean,那么后面相关的操作就不会执行了,只会执行一个AOP的代理操作
if (bean != null) {
// 虽然这个Bean被短路了,意味着不需要经过后面的初始化阶段,但是如果需要代理的话,还是要进行AOP代理,这个地方的短路操作只是意味着我们直接在后置处理器中提供了一个准备充分的的Bean,这个Bean不需要进行初始化,但需不需要进行代理,任然由AbstractAutoProxyCreator的applyBeanPostProcessorsBeforeInstantiation方法决定。在这个地方还是要调用一次Bean的初始化后置处理器保证Bean被完全的处理完
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
// bean != null基本会一直返回false,所以beforeInstantiationResolved这个变量也会一直为false
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

Para AbstractAutoProxyCreator em applyBeanPostProcessorsBeforeInstantiation este método de análise Deixe de lado até AOP realização de uma análise detalhada da fase de aprendizagem. Vamos só precisa saber que este método irá decidir se deve ou não gerar um objeto proxy para este follow-up em Bean.

análise processo doCreateBean

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 第一步:单例情况下,看factoryBeanInstanceCache这个缓存中是否有
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 第二步:这里创建对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 第三步:后置处理器处理
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
// 省略异常处理
}
mbd.postProcessed = true;
}
}

// 循环引用相关,源码阅读阶段再来解读这段代码,暂且就关注以下后置处理器的调用时机
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 第四步:调用后置处理器,早期曝光一个工厂对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

Object exposedObject = bean;
try {
// 第五步:属性注入
populateBean(beanName, mbd, instanceWrapper);
// 第六步:初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
// 省略异常处理
}
}

if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
// 省略异常处理
}
}
}
}

try {
// 第七步:注册需要销毁的Bean,放到一个需要销毁的Map中(disposableBeans)
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
// 省略异常处理
}

return exposedObject;
}

O primeiro passo: Quando factoryBeanInstanceCache não está vazio?

if (mbd.isSingleton()) {
// 第一步:单例情况下,看factoryBeanInstanceCache这个缓存中是否有
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}

Este código é muito complicado para entrar, eu estou aqui para simplesmente usar a seguinte teoria para explicar:

Suponha agora temos uma IndexService, ele tem uma propriedade de A, o seguinte código:

@Component
public class IndexService {
@Autowired
A a;

public A getA() {
return a;
}
}

E esta é a forma FactroyBean Uma configuração, como segue:

@Component
public class MyFactoryBean implements SmartFactoryBean {
@Override
public A getObject() throws Exception {
return new A();
}
@Override
public Class<?> getObjectType() {
return A.class;
}
// 这个地方并不一定要配置成懒加载,这里只是为了让MyFactoryBean这个Bean在IndexService之后实例化
@Override
public boolean isEagerInit() {
return false;
}
}

Nós pensamos sobre um problema no topo deste cenário, quando IndexService Para completar a injeção de propriedade, Primavera como você faria isso?

Primavera já sabe IndexService para injetar uma propriedade do tipo A, por isso vai ser analisado através de todos BeanDefinition, então cada BeanDefinition o tipo não é o tipo A, semelhante ao seguinte:

for (String beanName : this.beanDefinitionNames) {
// 1.获取BeanDefinition
// 2.根据BeanDefinition中的定义判断是否是一个A
}

Tais julgamentos na maioria dos casos acima é verdade, mas para uma de feijão especial não é o suficiente para que nós introduzimos mais cedo FactoryBean, porque o nosso objectivo não está configurado FactoacryBean diretamente FactoryBean o próprio Bean, mas falta através do seu método getObject vai se opor em um recipiente de Primavera, por isso, quando atravessamos uma BeanDefinition, e este é um FactoacryBean BeanDefinition quando você precisa fazer um tratamento especial, sabemos que existe um método GetObjectType FactoacryBean, podemos obter através deste método este tipo de objeto a ser criado FactoacryBean, se é que podemos chamar esse método, em seguida, uma vez que não pode determinar se este é um tipo de um.

No entanto, em nosso exemplo acima, desta vez MyFactoryBean ainda não foi criado. Portanto, neste momento vai Primavera instanciar MyFactoryBean, em seguida, chamar seus métodos GetObjectType, não determinar o tipo, atributo e, finalmente, a injeção, a seguinte pseudo-código:

for (String beanName : this.beanDefinitionNames) {
// 1.获取BeanDefinition
// 2.如果不是一个FactoacryBean,直接根据BeanDefinition中的属性判断
if(不是一个FactoacryBean){
//直接根据BeanDefinition中的属性判断是不是A
}
// 3.如果是一个FactoacryBean
if(是一个FactoacryBean){
// 先创建这个FactoacryBean,然后再调用getObjectType方法了
}
}

Nós podemos de acordo com nossa própria depuração do código acima, eu estou aqui para manter uma imagem de depuração.

Passo 2: criar o objecto (createBeanInstance)

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 获取到解析后的beanClass
Class<?> beanClass = resolveBeanClass(mbd, beanName);

// 忽略异常处理
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}

// 获取工厂方法,用于之后创建对象
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// 原型情况下避免多次解析
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}

// 跟后置处理器相关,我们主要关注这行代码
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}

// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}

// 默认使用无参构造函数创建对象
return instantiateBean(beanName, mbd);
}

Quando um objeto é criado, o resto do código não fazemos muita atenção. Deixe-nos saber no processo de criação do objeto, Primavera chamará um pós-processador para inferir o construtor.

O terceiro passo: applyMergedBeanDefinitionPostProcessors

BeanDefinition após a aplicação de fusão, Primavera-se usar isso para fazer alguns metadados cache de anotação.

Nós AutowiredAnnotationBeanPostProcessor método deste olhar aula sobre o seu papel correspondente

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 这个方法就是找到这个正在创建的Bean中需要注入的字段,并放入缓存中
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}

Passo Quatro: getEarlyBeanReference

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 在这里保证注入的对象是一个代理的对象(如果需要代理的话),主要用于循环依赖
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}

injeção de propriedades

Passo Cinco: Propriedades de injecção (populateBean)

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
// 省略异常
}
else {
return;
}
}

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { // 主要判断之后是否需要进行属性注入
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

// 自动注入模型下,找到合适的属性,在后续方法中再进行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 精确注入下,在这里完成属性注入
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
// 一般不会进行这个方法
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}

if (pvs != null) {
// XML配置,或者自动注入,会将之前找到的属性在这里进行注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

Ao longo do processo acima, temos nos concentrado em um método, postProcessProperties, ponto de injeção encontrada pelo método postProcessMergedBeanDefinition, método de injeção a este ponto antes desta vontade. Após a conclusão da propriedade injeção, eles começaram inicializado, o processo de inicialização no último artigo foi introduzido, não repeti-los aqui.

resumo

Nestes dois artigos, todos nós temos de ciclo de vida de feijão para fazer uma análise detalhada, é claro, há algum código complexo, mas sem questionar, porque depois vai escrever uma série de artigos dedicados análise de código fonte. Podemos nos concentrar em meu artigo de acompanhamento. Feijão por todo o ciclo de vida do desenho pode ser resumido como se segue

site oficial da Primavera ler a série (nove): Spring Bean no ciclo de vida (inferior)

 

Primeiro de tudo, todo o ciclo de vida do nosso feijão pode ser dividido em duas partes

  1. criar
  2. destruir

Para a fase de criação, que por sua vez são divididos em três etapas

  • instanciação
  • injeção de propriedades
  • inicialização

Podemos ver que em todo o processo BeanPostPorcessor intercaladas execução, assistida Spring Bean completado todo o ciclo de vida.

 


Leitura recomendada

site oficial da Primavera ler a série (a): Recipiente Primavera e instanciado

site oficial da Primavera ler a série (B): injeção de dependência Primavera e método de injeção

site oficial da Primavera leia as séries (três): injetados automaticamente com injeção precisa

Acho que você gosta

Origin www.cnblogs.com/Java3272858604/p/12583880.html
Recomendado
Clasificación