Author: Xiao Fu Ge
Blog: https://bugstack.cn
Precipitate, share and grow, so that you and others can gain something! 😄
catalogue
Jingdong coupon https://www.fenfaw.net/- [x] Chapter 1: opening introduction, I'm going to take you to Spring!
- [x] Chapter 2: try the ox knife and implement a simple Bean container
- [x] Chapter 3: first show your skills and use design patterns to realize the definition, registration and acquisition of Bean
- [x] Chapter 4: emerging, class instantiation strategy with constructor based on Cglib
- [x] Chapter 5: a blockbuster, injecting attributes into Bean objects and relying on the functional implementation of beans
- [x] Chapter 6: design and implementation of resource loader from spring XML parsing and registering Bean objects
- [x] Chapter 7: invincible, implementation of application context, automatic identification, resource loading and extension mechanism
- [] Chapter 8: to be filed
1, Foreword
You can't write this code dead!
According to the experience of project implementation, when we undertake urgent product needs, we usually choose to expand in the original similar projects. If there is no reserve of relevant types of projects, we may also choose to temporarily build a project to meet the needs of products. But at this time, we will encounter very practical problems. Choosing a complete design and development may not meet the online time, and the temporary patchwork completion demand may not have the ability to respond to the temporary adjustment of the product after online.
What are the adjustments after the launch? As soon as the project was launched, it had been in operation for less than half a day. The boss found that the amount of configured activities seemed to be too small. Users didn't come and couldn't cut leeks. Get in touch with the products in the middle of the night. Come here. You give me this change and that repair. Enlarge the per capita discount of 10000 yuan, and put the word "possible" in the back. Then adjust the preferential bonus pool configuration from 10 yuan to 11 yuan. Quickly, quickly, quickly modify it. If you modify it, we can earn 100 million!!!
Good guy, the project is a pile of temporary development. There is no background system, configuration center and module splitting. The boss changes it sentence by sentence, and the product is used to convey and urge. Finally, the back pot is R & D. You can't write it dead. The preferential configuration has to be taken out. The copy is also distributed in the background. The input parameter of this interface is also written dead. Write a new interface! The operation was fierce as a tiger, the R & D moved bricks and repaired interfaces, the operation tossed for several nights, and finally PV150!
No matter how the business, product and operation are, as far as the R & D itself is concerned, it is necessary to avoid temporarily piling up a service as much as possible, especially in the early stage of team construction or when the operation ideas are often adjusted, we should pay more attention to the design details and implementation scheme. Even if you report the risk delay, don't let yourself take on a job that you know is a rotten pit.
This chapter says not to write the code dead, because we need to continue to expand new functions in the handwritten Spring framework. For example, before and after the definition and instantiation of a Bean, can we customize the extension and perform some modification, enhancement, recording and other operations on the Bean object? This process is basically the development of some middleware extensions you do when using the Spring container framework.
2, Objective
If you have developed Spring based technical components in your actual work, or learned about the design and development of SpringBoot middleware. Then you must inherit or implement the classes or interfaces exposed by Spring. In the implementation of the interface, you obtain the acquisition of BeanFactory and Bean objects, and do some operations on these contents, such as modifying Bean information, adding log printing, processing database routing, switching data sources, connecting to RPC service registration center, etc.
While adding an extension mechanism to the instantiation process of beans in the container, we also need to XML initialization and loading strategies are optimized, because we are unlikely to let the DefaultListableBeanFactory service developed for Spring itself be directly used by users. The modification points are as follows:
- DefaultListableBeanFactory and XmlBeanDefinitionReader are the methods we use for service function testing in the current Spring framework. They can well reflect how Spring loads xml and registers Bean objects. However, this method is Spring oriented and does not have certain scalability.
- Just as we now need to provide a method that can complete the extension of Bean objects during Bean initialization, it is difficult to achieve automatic processing. Therefore, we should integrate the function of Bean object extension mechanism with the packaging of Spring framework context to provide complete services.
3, Design
In order to meet the user-defined operations in the process of Bean object from registration to instantiation, you need to insert an interface class in the process of Bean definition and initialization, and the interface has an external to implement the services you need. Then, combined with the processing ability of Spring framework context, we can meet our target requirements. The overall design structure is shown in the figure below:
- The two interfaces that are satisfied with the extension of Bean objects are actually two very heavyweight interfaces in the Spring framework: beanfactorypost process and BeanPostProcessor. They are almost two necessary interfaces for people to use the Spring framework to add and develop their own requirements.
- Beanfactoryprocessor is a container extension mechanism built and provided by the Spring framework. It allows you to modify the Bean definition after the Bean object is registered but not instantiated.
- BeanPostProcessor is also an extension mechanism provided by Spring. However, BeanPostProcessor modifies or replaces the Bean object after the Bean object is instantiated. This part is closely related to the AOP to be implemented later.
- At the same time, if you just add these two interfaces without any packaging, it is still very troublesome for users. We hope to develop the context operation class of Spring and integrate the corresponding XML loading, registration, instantiation, new modification and extension, so that Spring can automatically scan our new services for users to use.
4, Realize
1. Engineering structure
small-spring-step-06 └── src ├── main │ └── java │ └── cn.bugstack.springframework │ ├── beans │ │ ├── factory │ │ │ ├── factory │ │ │ │ ├── AutowireCapableBeanFactory.java │ │ │ │ ├── BeanDefinition.java │ │ │ │ ├── BeanFactoryPostProcessor.java │ │ │ │ ├── BeanPostProcessor.java │ │ │ │ ├── BeanReference.java │ │ │ │ ├── ConfigurableBeanFactory.java │ │ │ │ └── SingletonBeanRegistry.java │ │ │ ├── support │ │ │ │ ├── AbstractAutowireCapableBeanFactory.java │ │ │ │ ├── AbstractBeanDefinitionReader.java │ │ │ │ ├── AbstractBeanFactory.java │ │ │ │ ├── BeanDefinitionReader.java │ │ │ │ ├── BeanDefinitionRegistry.java │ │ │ │ ├── CglibSubclassingInstantiationStrategy.java │ │ │ │ ├── DefaultListableBeanFactory.java │ │ │ │ ├── DefaultSingletonBeanRegistry.java │ │ │ │ ├── InstantiationStrategy.java │ │ │ │ └── SimpleInstantiationStrategy.java │ │ │ ├── support │ │ │ │ └── XmlBeanDefinitionReader.java │ │ │ ├── BeanFactory.java │ │ │ ├── ConfigurableListableBeanFactory.java │ │ │ ├── HierarchicalBeanFactory.java │ │ │ └── ListableBeanFactory.java │ │ ├── BeansException.java │ │ ├── PropertyValue.java │ │ └── PropertyValues.java │ ├── context │ │ ├── support │ │ │ ├── AbstractApplicationContext.java │ │ │ ├── AbstractRefreshableApplicationContext.java │ │ │ ├── AbstractXmlApplicationContext.java │ │ │ └── ClassPathXmlApplicationContext.java │ │ ├── ApplicationContext.java │ │ └── ConfigurableApplicationContext.java │ ├── core.io │ │ ├── ClassPathResource.java │ │ ├── DefaultResourceLoader.java │ │ ├── FileSystemResource.java │ │ ├── Resource.java │ │ ├── ResourceLoader.java │ │ └── UrlResource.java │ └── utils │ └── ClassUtils.java └── test └── java └── cn.bugstack.springframework.test ├── bean │ ├── UserDao.java │ └── UserService.java ├── common │ ├── MyBeanFactoryPostProcessor.java │ └── MyBeanPostProcessor.java └── ApiTest.java
Project source: official account "bugstack wormhole stack", reply: Spring column, get the complete source code.
The class relationship between Spring application context and Bean object extension mechanism is shown in Figure 7-3
- The whole class diagram mainly reflects the Spring application context and the implementation of Bean object extension mechanism.
- Start with the ApplicationContext interface that inherits the ListableBeanFactory interface, extend a series of abstract implementation classes of application context, and finally complete the implementation of ClassPathXmlApplicationContext class. This class is the last one given to users.
- At the same time, in the process of implementing the application context, the extension mechanism for beans is connected in series by defining two interfaces: BeanFactoryPostProcessor and BeanPostProcessor.
2. Define beanfactoryprocessor
cn.bugstack.springframework.beans.factory.config.BeanFactoryPostProcessor
public interface BeanFactoryPostProcessor { /** * After all beandefinitions are loaded and before instantiating the Bean object, provide a mechanism to modify the BeanDefinition property * * @param beanFactory * @throws BeansException */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
- In the Spring source code, there is a paragraph describing allow for custom modification of an application context's Bean definitions, adapting the Bean property values of the context's underlying Bean factory In fact, this interface is satisfied with providing a mechanism to modify the BeanDefinition property after all beandefinitions are loaded and before instantiating the Bean object.
3. Define BeanPostProcessor
cn.bugstack.springframework.beans.factory.config.BeanPostProcessor
public interface BeanPostProcessor { /** * This method is executed before the Bean object executes the initialization method * * @param bean * @param beanName * @return * @throws BeansException */ Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; /** * This method is executed after the Bean object executes the initialization method * * @param bean * @param beanName * @return * @throws BeansException */ Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
- In the Spring source code, there is a paragraph describing factory hook that allows for custom modification of new Bean instances, e.g. checking for market interfaces or wrapping them with proxies That is, it provides extension points for modifying newly instantiated Bean objects.
- In addition, this interface provides two methods: postProcessBeforeInitialization is used to execute this method before the Bean object executes the initialization method, and postProcessAfterInitialization is used to execute this method after the Bean object executes the initialization method.
4. Define context interface
cn.bugstack.springframework.context.ApplicationContext
public interface ApplicationContext extends ListableBeanFactory { }
- Context is a new service package to realize the application context function this time
- ApplicationContext, which inherits from ListableBeanFactory, inherits BeanFactory methods, such as some getBean methods. In addition, ApplicationContext itself is a Central interface, but there is no need to add some access ID and parent class context, so there is no definition of interface method for the time being.
cn.bugstack.springframework.context.ConfigurableApplicationContext
public interface ConfigurableApplicationContext extends ApplicationContext { /** * Refresh container * * @throws BeansException */ void refresh() throws BeansException; }
- ConfigurableApplicationContext inherits from ApplicationContext and provides the core method refresh. If you have seen some Spring source code, you will see this method. The next step is to complete the operation process of refreshing the container in the context implementation.
5. Application context abstract class implementation
cn.bugstack.springframework.context.support.AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { @Override public void refresh() throws BeansException { // 1. Create BeanFactory and load BeanDefinition refreshBeanFactory(); // 2. Obtain BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 3. Before Bean instantiation, execute beanfactoryprocessor (invoke factory processors registered as beans in the context.) invokeBeanFactoryPostProcessors(beanFactory); // 4. BeanPostProcessor needs to perform the registration operation before other Bean objects are instantiated registerBeanPostProcessors(beanFactory); // 5. Instantiate the singleton Bean object in advance beanFactory.preInstantiateSingletons(); } protected abstract void refreshBeanFactory() throws BeansException; protected abstract ConfigurableListableBeanFactory getBeanFactory(); private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class); for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) { beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); } } private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class); for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) { beanFactory.addBeanPostProcessor(beanPostProcessor); } } //... getBean, getBeansOfType, getBeanDefinitionNames methods }
- AbstractApplicationContext inherits DefaultResourceLoader to handle spring XML configuration resource loading.
- Then define the implementation process in refresh(), including:
-
- Create BeanFactory and load BeanDefinition
-
- Get BeanFactory
-
- Before Bean instantiation, execute beanfactoryprocessor (invoke factory processors registered as beans in the context.)
-
- BeanPostProcessor needs to perform the registration operation before other Bean objects are instantiated
-
- Instantiate the singleton Bean object in advance
-
- In addition, the defined abstract methods, refreshBeanFactory(), getBeanFactory(), are implemented by other abstract classes that inherit this abstract class.
6. Obtain Bean factory and load resources
cn.bugstack.springframework.context.support.AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { private DefaultListableBeanFactory beanFactory; @Override protected void refreshBeanFactory() throws BeansException { DefaultListableBeanFactory beanFactory = createBeanFactory(); loadBeanDefinitions(beanFactory); this.beanFactory = beanFactory; } private DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(); } protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory); @Override protected ConfigurableListableBeanFactory getBeanFactory() { return beanFactory; } }
- In refreshBeanFactory(), it mainly obtains the instantiation of DefaultListableBeanFactory and the loading operation loadbean definitions (beanfactory) of resource configuration. After loading, it can complete the spring The definition and registration of Bean objects in the XML configuration file also includes the configuration Bean information that implements the interfaces BeanFactoryPostProcessor and BeanPostProcessor.
- However, at this time, the resource loading only defines an abstract class method loadBeanDefinitions(DefaultListableBeanFactory beanFactory), which continues to be inherited and implemented by other abstract classes.
7. Loading of configuration information in context
cn.bugstack.springframework.context.support.AbstractXmlApplicationContext
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableApplicationContext { @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory, this); String[] configLocations = getConfigLocations(); if (null != configLocations){ beanDefinitionReader.loadBeanDefinitions(configLocations); } } protected abstract String[] getConfigLocations(); }
- In the implementation of loadBeanDefinitions method of AbstractXmlApplicationContext abstract class, XmlBeanDefinitionReader class is used to handle the operation of XML file configuration information.
- At the same time, an abstract class method, getConfigLocations(), is left here. This method is to get the address description of the configuration information from the entry context class.
8. Application context implementation class (ClassPathXmlApplicationContext)
cn.bugstack.springframework.context.support.ClassPathXmlApplicationContext
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { private String[] configLocations; public ClassPathXmlApplicationContext() { } /** * Load the BeanDefinition from the XML and refresh the context * * @param configLocations * @throws BeansException */ public ClassPathXmlApplicationContext(String configLocations) throws BeansException { this(new String[]{configLocations}); } /** * Load the BeanDefinition from the XML and refresh the context * @param configLocations * @throws BeansException */ public ClassPathXmlApplicationContext(String[] configLocations) throws BeansException { this.configLocations = configLocations; refresh(); } @Override protected String[] getConfigLocations() { return configLocations; } }
- ClassPathXmlApplicationContext is a specific application context method provided to users externally.
- After inheriting the function separation implementation of AbstractXmlApplicationContext and layers of abstract classes, the implementation of ClassPathXmlApplicationContext is much simpler. It mainly calls the methods in the inherited abstract classes and provides the address information of the configuration file.
9. Complete pre-processing and post-processing when creating a Bean
cn.bugstack.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); @Override protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException { Object bean = null; try { bean = createBeanInstance(beanDefinition, beanName, args); // Populate the Bean with attributes applyPropertyValues(beanName, bean, beanDefinition); // Execute the initialization method of Bean and the pre and post processing methods of BeanPostProcessor bean = initializeBean(beanName, bean, beanDefinition); } catch (Exception e) { throw new BeansException("Instantiation of bean failed", e); } addSingleton(beanName, bean); return bean; } public InstantiationStrategy getInstantiationStrategy() { return instantiationStrategy; } public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) { this.instantiationStrategy = instantiationStrategy; } private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) { // 1. Execute BeanPostProcessor Before processing Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName); // To be completed: invokeinitialmethods (beanname, wrapped bean, beandefinition); invokeInitMethods(beanName, wrappedBean, beanDefinition); // 2. Execute BeanPostProcessor After processing wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName); return wrappedBean; } private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition) { } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (null == current) return result; result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (null == current) return result; result = current; } return result; } }
- After implementing the BeanPostProcessor interface, two interface methods will be involved, postProcessBeforeInitialization and postProcessAfterInitialization, which respectively act on the additional processing before and after the initialization of the Bean object.
- That is, when creating a Bean object, you need to add initializeBean(beanName, bean, beanDefinition) in the createBean method; Operation. This operation is mainly used for methods applyBeanPostProcessorsBeforeInitialization and applyBeanPostProcessorsAfterInitialization.
- In addition, it should be mentioned that the two methods of applybeanprostprocessorsbeforeinitialization and applybeanprostprocessorsafterinitialization are newly added in the interface class AutowireCapableBeanFactory.
5, Testing
1. Preparation in advance
cn.bugstack.springframework.test.bean.UserDao
public class UserDao { private static Map<String, String> hashMap = new HashMap<>(); static { hashMap.put("10001", "Little brother Fu"); hashMap.put("10002", "Eight cups of water"); hashMap.put("10003", "A Mao"); } public String queryUserName(String uId) { return hashMap.get(uId); } }
cn.bugstack.springframework.test.bean.UserService
public class UserService { private String uId; private String company; private String location; private UserDao userDao; public void queryUserInfo() { return userDao.queryUserName(uId); } // ...get/set }
- Dao and Service are often used in our daily development. Inject UserDao into UserService to reflect the dependency of Bean attribute.
- In addition, two new attribute information, company and location, are added here to test the function of BeanPostProcessor and beanfactorypost processor on the extension of Bean attribute information.
2. Implement BeanPostProcessor and beanfactorypost processor
cn.bugstack.springframework.test.common.MyBeanFactoryPostProcessor
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService"); PropertyValues propertyValues = beanDefinition.getPropertyValues(); propertyValues.addPropertyValue(new PropertyValue("company", "Change to: byte runout")); } }
cn.bugstack.springframework.test.common.MyBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { UserService userService = (UserService) bean; userService.setLocation("Changed to: Beijing"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
- If you have done some component development in Spring, you must be very familiar with these two classes. The test in this paper also implements these two classes and does some operations on Bean objects in the instantiation process.
3. Configuration file
Basic configuration, no BeanFactoryPostProcessor, BeanPostProcessor, implementation class
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="cn.bugstack.springframework.test.bean.UserDao"/> <bean id="userService" class="cn.bugstack.springframework.test.bean.UserService"> <property name="uId" value="10001"/> <property name="company" value="tencent"/> <property name="location" value="Shenzhen"/> <property name="userDao" ref="userDao"/> </bean> </beans>
Enhanced configuration, including BeanFactoryPostProcessor, BeanPostProcessor and implementation classes
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="cn.bugstack.springframework.test.bean.UserDao"/> <bean id="userService" class="cn.bugstack.springframework.test.bean.UserService"> <property name="uId" value="10001"/> <property name="company" value="tencent"/> <property name="location" value="Shenzhen"/> <property name="userDao" ref="userDao"/> </bean> <bean class="cn.bugstack.springframework.test.common.MyBeanPostProcessor"/> <bean class="cn.bugstack.springframework.test.common.MyBeanFactoryPostProcessor"/> </beans>
- Two configuration files are provided here. One does not contain BeanFactoryPostProcessor and BeanPostProcessor, and the other contains. The reason for this configuration is mainly to verify how to operate when using the newly added application context of Spring and not using it.
4. No application context
@Test public void test_BeanFactoryPostProcessorAndBeanPostProcessor(){ // 1. Initialize BeanFactory DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 2. Read configuration file & register Bean XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions("classpath:spring.xml"); // 3. After loading the BeanDefinition & before instantiating the bean, modify the attribute value of the BeanDefinition MyBeanFactoryPostProcessor beanFactoryPostProcessor = new MyBeanFactoryPostProcessor(); beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); // 4. After the Bean is instantiated, modify the Bean attribute information MyBeanPostProcessor beanPostProcessor = new MyBeanPostProcessor(); beanFactory.addBeanPostProcessor(beanPostProcessor); // 5. Get Bean object and call method UserService userService = beanFactory.getBean("userService", UserService.class); String result = userService.queryUserInfo(); System.out.println("Test results:" + result); }
- DefaultListableBeanFactory is familiar with how to create beanFactory and use XmlBeanDefinitionReader to load configuration files.
- The next step is to deal with mybeanfactorypost processor and MyBeanPostProcessor. One is to modify the attribute value of BeanDefinition before BeanDefinition is loaded & Bean instantiation, and the other is to modify the attribute information of Bean after Bean instantiation.
test result
Test result: little brother Fu,Change to: byte runout,Changed to: Beijing Process finished with exit code 0
- Through the test results, we can see that the attribute information we configured has been consistent with spring The XML configuration file is different.
5. Use application context
@Test public void test_xml() { // 1. Initialize BeanFactory ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springPostProcessor.xml"); // 2. Get Bean object and call method UserService userService = applicationContext.getBean("userService", UserService.class); String result = userService.queryUserInfo(); System.out.println("Test results:" + result); }
- In addition, it is much more convenient to use the newly added ClassPathXmlApplicationContext application context class. This is the class for users. Here, you can hand over the configuration file to ClassPathXmlApplicationContext step by step, and there is no need to manage some custom implemented Spring interface classes.
test result
Test result: little brother Fu,Change to: byte runout,Changed to: Beijing Process finished with exit code 0
- This is the same as the test result without application context, but now it is more convenient.
6, Summary
- This paper mainly adds two very important interfaces in the Spring framework, beanfactorypost process and BeanPostProcessor. At the same time, it also adds the implementation of application context. The definition of ApplicationContext interface is an interface that inherits the newly added functions outside BeanFactory. It can meet the functions of automatic identification, resource loading, container event, listener and so on, At the same time, for example, some internationalization support and automatic initialization of singleton beans can also be implemented and extended in this class.
- Through the implementation of this article, you will have a good understanding of beanfactorypost process and BeanPostProcessor. When developing Spring Middleware in the future, if you need to obtain Bean objects and modify some attribute information, you can use these two interfaces. At the same time, BeanPostProcessor is also the key to realize AOP aspect technology.
- Someone asked: there are so many interview questions, but the work is not needed. Is it GAHA?, GAHA, do you say that when you drive on the bridge, you will hit the guardrails on both sides every time? If you don't, don't fix it. Just lay a flat plate and save materials. In fact, learning the principles of core technology is more helpful for you to complete more complex architecture design. When your knowledge can more fully cover the needs you undertake, you can better make a reasonable architecture and landing.
7, Series recommendation
- Little brother Fu, a code farmer with "sideline"!
- After a long wait, little brother Fu's "re learning Java design pattern" was finally published, color printing & paper!
- Half a year's recruitment screened 400 + resumes and told you how to write, which is easy to be teased!
- A code review, almost can't pass the probation period!
- Summary of learning route resources from four years of university to five years of graduation