Spring AOP implements source code analysis (2)

The implementation of Spring AOP can be divided into three parts:
1. Register the specific implementation class of the AOP function

2. AOP entry when instantiating ordinary beans

3. AOP cuts into the specific process

 

2.  AOP entry when instantiating ordinary beans

The ApplicationContext main process will ensure that the registration and instantiation of the BeanPostProcessor is completed first, which ensures that when the ordinary bean is instantiated, all the BeanPostProcessors have been instantiated

 

public void refresh() throws BeansException, IllegalStateException {
  ......
  // Register bean processors that intercept bean creation.
  // complete all BeanPostProcessor instantiations
  registerBeanPostProcessors(beanFactory);
  ......
  // Instantiate all remaining (non-lazy-init) singletons.
  // instantiate all normal singleton beans
  finishBeanFactoryInitialization(beanFactory);
  // Last step: publish corresponding event.
  finishRefresh();
}

 

The operation of instantiating a bean, the process will call createBean(),

AOP implementation class, there are two sets of functions with almost the same name, pay attention to the distinction to understand

 

// This pair is used before calling createBean, Instantiation means instantiation
postProcessBeforeInstantiation
postProcessAfterInstantiation

// This pair is used after the bean has been created in createBean, Initialization means initialization
postProcessBeforeInitialization
postProcessAfterInitialization

 

protected Object createBean(){
    ......
    try {
        // Called before the real bean is instantiated, if BeanPostProcessor creates a bean, skip the following doCreateBean and return directly
        // This will call the above Instantiation series, eventually return null, and enter doCreateBean
        Object bean = resolveBeforeInstantiation(beanName, mbd);
        if (bean != null) {
             return bean;
        }
    }
    // After the real bean is instantiated, call the method of BeanPostProcessor to change the bean again
    Object beanInstance = doCreateBean(beanName, mbd, args);
    ......
}

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    ......
    // 执行 beanPostProcessor.postProcessorBeforeInstantiation()
    // Note the name of this method BeforeInstantiation
    bean = applyBeanPostProcessorBeforeInstantiation (mbd.getBeanClass (), beanName);
    // Only go to the next step if the bean returned by the previous method is not null
    if(bean !=null){
        // 执行 beanPostProcessor.postProcessorAfterInstantiation()
        bean = applyBeanPostProcessorBeforeInstantiation (bean, beanName);
    }
}

 

The aop of ordinary beans takes effect, using the Initialization series of methods, tracking doCreateBean(beanName, mbd, args)

 

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
......				
  if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
	@Override
	public Object getObject() throws BeansException {
	try {
          // Start the process of creating the bean
	  return createBean(beanName, mbd, args);
	}
     }
......
}

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
......
  Object beanInstance = doCreateBean(beanName, mbdToUse, args);
......
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {
......
try {
  populateBean (beanName, mbd, instanceWrapper);
  if (exposedObject != null) {
    // The bean has been instantiated before, here is the final initialization init, aop intervenes
    exposedObject = initializeBean(beanName, exposedObject, mbd);
  }
}
......
}

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
......
  if (mbd == null || !mbd.isSynthetic()) {
    // Ordinary beans perform unified post processing, and aop is implemented in it
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  }
  return wrappedBean;
......
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
  Object result = existingBean;
  for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    // Call the real implementation method entry of AOP
    result = beanProcessor.postProcessAfterInitialization(result, beanName);
    if (result == null) {
      return result;
    }
  }
  return result;
}



 

2.  AOP entry when instantiating ordinary beans

The ApplicationContext main process will ensure that the registration and instantiation of the BeanPostProcessor is completed first, which ensures that when the ordinary bean is instantiated, all the BeanPostProcessors have been instantiated

 

public void refresh() throws BeansException, IllegalStateException {
  ......
  // Register bean processors that intercept bean creation.
  // complete all BeanPostProcessor instantiations
  registerBeanPostProcessors(beanFactory);
  ......
  // Instantiate all remaining (non-lazy-init) singletons.
  // instantiate all normal singleton beans
  finishBeanFactoryInitialization(beanFactory);
  // Last step: publish corresponding event.
  finishRefresh();
}

 

The operation of instantiating a bean, the process will call createBean(),

AOP implementation class, there are two sets of functions with almost the same name, pay attention to the distinction to understand

 

// This pair is used before calling createBean, Instantiation means instantiation
postProcessBeforeInstantiation
postProcessAfterInstantiation

// This pair is used after the bean has been created in createBean, Initialization means initialization
postProcessBeforeInitialization
postProcessAfterInitialization

 

protected Object createBean(){
    ......
    try {
        // Called before the real bean is instantiated, if BeanPostProcessor creates a bean, skip the following doCreateBean and return directly
        // This will call the above Instantiation series, eventually return null, and enter doCreateBean
        Object bean = resolveBeforeInstantiation(beanName, mbd);
        if (bean != null) {
             return bean;
        }
    }
    // After the real bean is instantiated, call the method of BeanPostProcessor to change the bean again
    Object beanInstance = doCreateBean(beanName, mbd, args);
    ......
}

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    ......
    // 执行 beanPostProcessor.postProcessorBeforeInstantiation()
    // Note the name of this method BeforeInstantiation
    bean = applyBeanPostProcessorBeforeInstantiation (mbd.getBeanClass (), beanName);
    // Only go to the next step if the bean returned by the previous method is not null
    if(bean !=null){
        // 执行 beanPostProcessor.postProcessorAfterInstantiation()
        bean = applyBeanPostProcessorBeforeInstantiation (bean, beanName);
    }
}

 

The aop of ordinary beans takes effect, using the Initialization series of methods, tracking doCreateBean(beanName, mbd, args)

 

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
......				
  if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
	@Override
	public Object getObject() throws BeansException {
	try {
          // Start the process of creating the bean
	  return createBean(beanName, mbd, args);
	}
     }
......
}

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
......
  Object beanInstance = doCreateBean(beanName, mbdToUse, args);
......
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {
......
try {
  populateBean (beanName, mbd, instanceWrapper);
  if (exposedObject != null) {
    // The bean has been instantiated before, here is the final initialization init, aop intervenes
    exposedObject = initializeBean(beanName, exposedObject, mbd);
  }
}
......
}

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
......
  if (mbd == null || !mbd.isSynthetic()) {
    // Ordinary beans perform unified post processing, and aop is implemented in it
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  }
  return wrappedBean;
......
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
  Object result = existingBean;
  for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    // Call the real implementation method entry of AOP
    result = beanProcessor.postProcessAfterInitialization(result, beanName);
    if (result == null) {
      return result;
    }
  }
  return result;
}



 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326404624&siteId=291194637