Spring source principle articles (a)

Spring source principle chapter - container initialization & Bean post-processors

IOC container is explained in this chapter show initialization process which is generally carried out some work, and the work principle and the postprocessor Bean BeanPostProcessor in the bottom.

Preparing the Environment

  • The compiler IDEA
  • maven依赖spring-context version:4.3.12.RELEASE
  • maven rely on JUnit Version: 4.11

BeanPostProcessor works

BeanPostProcessor interface implementation component, and marked with two breakpoint in vivo:

public class BeanPostProcessorDefinition implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessBeforeInitialization -->"+s+" = "+o);
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessorAfterInitialization -->"+s+"="+o);
        return o;
    }
}
复制代码

Check after commissioning method call stack as follows (Figure 1):

Stack initializeBean (initialization Bean) method call method, there is a similar to the following pseudocode:

initializeBean(param){
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
...
invokeInitMethods(beanName, wrappedBean, mbd);
...
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
复制代码

This generally means the first pseudo-code is performed before the method bean initialized and the bean initialization process, process after initialization the last execution. applyBeanPostProcessorsBeforeInitialization call stack is a method belonging to the ring, into a similar section of pseudocode:

applyBeanPostProcessorsBeforeInitialization(param)
			throws BeansException {
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessBeforeInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}
复制代码

This code is obtained by traversing all BeanPostProcessor, then one by one postProcessBeforeInitialization method rewriting is performed, if there is a method to return the bean is null, it will jump out of the loop, it means that the following postProcessBeforeInitialization method will not be executed. Similarly applyBeanPostProcessorsAfterInitialization executed after initialization method is the same. A general summary of post-processor Bean initialization process (FIG. 2):

Container initialization process

Speaking spring of IOC container are inseparable from the two interfaces BeanFactory and ApplicationContext, which ApplicationContext is a subinterface of BeanFactory, they may represent spring container. The method shown in FIG break point of the call stack can be used to analyze the work performed to initialize the container (the container to obtain AnnotationConfigApplicationContext example):

  • init: configuration class registration, call the refresh () refresh container

  • refresh process:

  • registerBeanPostProcessors (Param) registered Bean post-processors to intercept creation of Bean

    • It gets has defined the need to create objects BeanPostProcessor
    • BeanPostProcessor are distinguished implemented PriorityOrdered, Ordered the
    • Sunrise achieve PriorityOrdered interface BeanPostProcessor
    • Give the vessel registered BeanPostProcessor achieve Ordered interfaces
    • The last registration did not implement priority of the interface BeanPostProcessor (conventional post-processors)
    • Register the BeanPostProcessor, spring creates what actually stored in a container; The following processes are created Bean: 1, to create the Bean instance doCreateBean (Param) Method 2, populateBean (Param) to the bean property assignment Example 3, initializeBean (Param) : initialization Bean 4, invokeAwareMethods (): Bean implemented method for processing a callback interface Aware 5, post processor process: Scheme 2 of FIG.
    • beanFactory.addBeanPostProcessor: to create the finished BeanPostProcessor placed in a container

========== The above process is complete the registration and the creation of BeanPostProcessor

  • refresh process connected:
  • finishBeanFactoryInitialization (Param) to complete the BeanFactory initialization work, and the rest to create a single instance of the bean
  • Bean created a single instance method call stack: getBean-> doGetBean () -> getSingleton () - createBean-doCreateBean then is to repeat the above process to create Bean. This section details Bean create the source code to temporarily slow a slow, until the spring aspectJ source code analysis and then step back and analyze what were some operations from getBean to doCreateBean.

BeanPostProcessor in the bottom of the spring

In the spring, Bean Aware interface after being initially, you can get some of the corresponding resources, that is, custom components you want to use some of the components of the underlying Spring container (ApplicationContext, BeanFactory, xxx), then custom components on the need to achieve xxxxAware interfaces; methods when creating the object, it calls the interface specified injection-related components, the Spring underlying some of the components injected into the custom of the Bean; ApplicationContextAware be when Spring initialized instance Bean, you can through this interface current Spring context passed, i.e. spring containers obtained, the actual development is often packaged as a utility class (to facilitate access to the container acquires bean):

//将组件注册添加到容器中后可以直接当作工具类
public class SpringContextTool implements ApplicationContextAware {

    private static ApplicationContext context = null;

    public static Object getBean(String beanName) {
        return context.getBean(beanName);
    }

    public static <T> T getBean(Class<T> clazz){
        return context.getBean(clazz);
    }

    public static ApplicationContext getContext() {
        return context;
    }

    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        context = applicationContext;//打个断点
    }
}
复制代码

How it works: hit the override method breakpoints, view the method call stack container seen before bean initialization method execution, perform postProcessBeforeInitialization method postprocessor, the program jumped ApplicationContextAwareProcessor this class (the class implements the interface BeanPostProcessor ), postProcessBeforeInitialization method rewriting is performed, the jump invokeAwareInterfaces method to determine the current bean initialization time inherited the corresponding Aware, if a corresponding set method is invoked, passing the corresponding resources.

Similarly there EnvironmentAware EmbeddedValueResolverAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware example is also injected EmbeddedValueResolverAware As another spring assembly of the bottom, this may be achieved aware Spring obtain complete interface properties file property values:

public class PropertiesUtil implements EmbeddedValueResolverAware {

    private static StringValueResolver resolver;

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = resolver;
    }
    public static String getPropertiesValue(String key) {
        StringBuilder name = new StringBuilder("${").append(key).append("}");
        return resolver.resolveStringValue(name.toString());
    }
}
复制代码

It may be employed if desired properties file is getting a property value: propertiesUtil.getPropertiesValue ( "xxxxxxx") or @value ( "xxxx") to achieve the get property values. After playing a breakpoint find it and ApplicationContextAware principle is the same. It is judged when the current initialization bean inherited the corresponding Aware, if a corresponding set method is invoked, passing the corresponding resources. Source as follows:

private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}
复制代码

ServletContextAware, ServletConfigAware and several other principle is almost similar. Similarly there are also realized BeanValidationPostProcessor BeanPostProcessor interface for data validation, as well as InitDestroyAnnotationBeanPostProcessor also implements this interface, mainly for processing JSR250 few annotations, the AutowiredAnnotationBeanPostProcessor also implements the interface, for processing @autowired Notes loaded bean. In short, Bean assignment, inject other components, @ autowired, @ Async, life cycle and so on are done using BeanPostProcessor. Here are some principles to use and re-analysis in the next chapter and make up a flow chart.

Guess you like

Origin blog.csdn.net/weixin_33797791/article/details/91374715