From the initial simple handwritten article to the current source code analysis article, the whole spring MVC has been completed.
We can see that various callbacks, such as AOP and MVC, are processed through callbacks. This article will take a look at what other practical uses spring has besides being used as a framework.
First, let's take a look at the callback of the spring bean creation process again
createBeanInstance -> Constructor -> setter methods ->
BeanNameAware.setBeanName ->BeanClassLoaderAware.setBeanClassLoader -> BeanFactoryAware.setBeanFactory -> BeanPostProcessor.postProcessBeforeInitialization ->
InitializingBean.afterPropertiesSet -> BeanPostProcessor.postProcessAfterInitialization
1. Constructor: initializes the object through the construction method, class newInstance()
2. setter methods, attribute method assignment, and dependency injection. There is a detailed explanation of dependency injection before, so I won't say more
3. BeanNameAware.setBeanName
- Get the beanName of the current implementation class and prepare the following code. When initializing the current class, the beanName will be called back to this method
@Component public class TestBeanNameAware implements BeanNameAware { @Override public void setBeanName(String name) { System.out.println("#Obtain beanname of TestBeanNameAware implementation class: "+ name"); } }
4. BeanClassLoaderAware.setBeanClassLoader
- Gets the ClassLoader of the currently loaded class
@Component public class TestBeanClassLoaderAware implements BeanClassLoaderAware { @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("#Get the classloader of the currently loaded class: "+ classloader"); } }
5. BeanFactoryAware.setBeanFactory
- Get all the bean s in the container. The common ApplicationContextAware also has the same function
@Component public class TestBeanFactoryAware implements BeanFactoryAware { @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("#Get the container of the management bean: "+ beanFactory.getClass().getName()); // Object nameAware = beanFactory.getBean("testBeanNameAware"); System.out.println(nameAware); } }
6. BeanPostProcessor.postProcessBeforeInitialization ,postProcessAfterInitialization
- Callbacks before and after bean initialization can return inheritance classes or proxy classes before and after bean initialization. aop is a typical example
@Component public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // System.out.println("before initialization:" + bean. Getclass() getName()+","+beanName); if(beanName.equals("com.example.demo.action.TestAction")){ System.out.println("After initialization:"+bean.getClass().getName()+","+beanName); return new Test1Action(); //Set to implement class or inheritance class to dynamically modify bean initialization } return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // System.out.println("after initialization:" + bean. Getclass() getName()+","+beanName); if(beanName.equals("com.example.demo.action.TestAction")){ System.out.println("After initialization:"+bean.getClass().getName()+","+beanName); } return null; } }
7. InitializingBean.afterPropertiesSet
- Initial callback of the current class. Case: implementation of MVC
@Component public class TestInitializingBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("#After initialization, the current class callback is completed, and the post callback is preceded by ""); } }
8. ApplicationContextAware obtains container context, which is commonly used. I won't elaborate
9. BeanDefinitionRegistryPostProcessor
- Custom registered bean s or properties
@Component public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { /** * Implement the custom bean and register it with BeanDefinitionRegistry * @param registry * @throws BeansException */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { //The TestAction does not have any loaded identifier. You can use this method to register mybatis with the container BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TestAction.class); registry.registerBeanDefinition(TestAction.class.getName(),builder.getBeanDefinition()); System.out.println("Register custom bean:"+builder.getBeanDefinition().getBeanClass()); } /** * It is mainly used to customize and modify the attribute values in the held bean s * @param beanFactory * @throws BeansException */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { for (String definitionName : beanFactory.getBeanDefinitionNames()) { if ("com.example.demo.action.TestAction".equals(definitionName)) { System.out.println("###beanName:" + definitionName); BeanDefinition definition = beanFactory.getBeanDefinition(definitionName); //Get the defined value of the bean and dynamically modify the value. setter method is required MutablePropertyValues pv = definition.getPropertyValues(); pv.addPropertyValue("name", "Wang Er Ma Zi"); System.out.println("###TestAction#name (reassign) "; break; } } } }
10. FactoryBean.getObject(), getObjectType()
- Class that implements FactoryBean. When the container initializes this class, it will call the current getObject() method
//You can also register the class yourself. This method will also be called when the class is initially registered BeanDefinitionBuilder builder1 = BeanDefinitionBuilder.genericBeanDefinition(TestFatoryBean.class); registry.registerBeanDefinition("aaabbbccc",builder1.getBeanDefinition());
@Component public class TestFatoryBean implements FactoryBean { /** * When initializing this class, the definition of testfactorybean has been replaced by testfactorybean 1 * TestFactoryBean1 can be annotated in other classes directly * @return Returned object instance * @throws Exception */ @Override public Object getObject() throws Exception { System.out.println("#Initialize testfactorybean getObject()"); return new TestFactoryBean1(); } /** * @return Object type returned */ @Override public Class<?> getObjectType() { System.out.println("#Initialize testfactorybean getObjectType()"); return TestFactoryBean1.class; } }
11. AbstractApplicationContext
- Mainly container related events
@Component public class TestAbstractApplicationContext extends AbstractApplicationContext { @Override protected void refreshBeanFactory() throws BeansException, IllegalStateException { System.out.println("#Refresh container event ""); } @Override protected void closeBeanFactory() { System.out.println("#Close container event ""); } /** * Return the existing container 𞓜 custom container * @return * @throws IllegalStateException */ @Override public ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException { return null; } }
12. DeferredImportSelector extends ImportSelector
- Customize the class to be imported, and pass in the class name list for automatic assembly
- Other classes are required. The annotation @ Import(TestDeferredImportSelector.class) is used
First usage:
public class TestDeferredImportSelector implements ImportSelector { //Directly implement the package name path of the incoming class @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { System.out.println("#Delay importing importingClassMetadata to be loaded ""); return new String[]{TestImportAction.class.getName()}; } }
The second usage can be implemented in groups:
public class TestDeferredImportSelector implements DeferredImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return null; } /** * If grouping is implemented, priority is given to grouping, which is the implementation class of de grouping * @return Returns the class that implements grouping (DeferredImportSelector.Group) */ @Override public Class<? extends Group> getImportGroup() { return Test123.class; } private static class Test123 implements DeferredImportSelector.Group{ AnnotationMetadata annotationMetadata; @Override public void process(AnnotationMetadata metadata, DeferredImportSelector selector) { System.out.println("#Delay the introduction of the process to be loaded "); this.annotationMetadata = metadata; //Here, you can make groups according to the original data, so that each group can load different classes } @Override public Iterable<Entry> selectImports() { System.out.println("#Delay importing the selectImports to be loaded "); String[] strings = {TestImportAction.class.getName()}; return Arrays.asList(strings).stream(). map((className) -> new Entry(this.annotationMetadata,className)).collect(Collectors.toList()); } } }
At present, there are so many things that can be sorted out. There must be others who are not considerate. There is not much in-depth research here
That is the whole content of this chapter.
Previous: Spring source code analysis fourth bullet - MVC analysis
Next: The sixth bullet of SpringMvc source code analysis - handwritten high imitation version based on SpringMvc source code
The method of reading is in order and step by step, familiar reading and careful thinking