When we are working on a project, we will use a listener to obtain Spring configuration files, and then take out the beans we need from it. For example, to make the website homepage. Assuming that the background business logic of the product is done well, we need to create a listener, and query the homepage data at the project startup and put it into the application, that is, the method of calling the background product business logic in the listener, that is, we need to obtain the corresponding beans configured in Spring in the listener. Create the listener first:
1. Create an InitDataListener
Create a listener InitDataListener inherits ServletContextListener:
/** * @Description: TODO (used to initialize data when project starts) * @author eson_15 * */ //@Component // Listener is a component of the web layer. It is instantiated by tomcat, not instantiated by Spring. Can't be put in Spring public class InitDataListener implements ServletContextListener { private ProductService productService = null;//productService defines the business logic related to the product @Override public void contextDestroyed(ServletContextEvent event) { } @Override public void contextInitialized(ServletContextEvent event) { } }And configure the listener in web.xml:
As mentioned above, some business logic of the product is defined in the productService, and this productService is handed over to Spring for management. So how do we get this object? The first thing to be sure is: we can’t get it out by ourselves, because if it comes out, it has nothing to do with Spring’s IoC… There are three main ways to achieve it. We analyze it one by one, and finally compare the advantages and disadvantages.
2. Load the beans.xml file directly
This method is simple and crude. Don’t you need to load the configuration file? OK, I'll load it, as follows:
//@Component // Listener is a component of the web layer. It is instantiated by tomcat, not Spring. Can't be put in Spring public class InitDataListener implements ServletContextListener { private ProductService productService = null; //productService defines the business logic related to the product @Override public void contextDestroyed(ServletContextEvent event) { } @Override public void contextInitialized(ServletContextEvent event) { // Get the business logic class productService query product information ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); productService = (ProductService) context.getBean("productService"); System.out.println(productService); //Output to see if you get it//The following are the specific productService-related operations... } }This method is completely fine, and the idea is very clear. First load the configuration file beans.xml and then get the bean. However, after starting tomcat, let's take a look at the information output from the console:
At this point, we should find the disadvantages of this method. The configuration files were loaded twice, which means that those beans were instantiated twice. Judging from the printed information, we got the beans that we loaded the configuration files ourselves and were instantiated. This method is obviously undesirable.
3. Get from ServletContext
From the above method, we can at least know that Spring has loaded the configuration file once through its listener. We don’t need to load it again. It is easy to think that if we know where Spring has been loaded, then we can get the configuration file from there. Let’s take a look at the process of loading the configuration file in Spring:
In the above figure (irrelevant code is omitted), the ContextLoaderListener is the Spring listener we configured in web.xml. It also implements the ServletContextListener and inherits the ContextLoader. In the listener, the configuration file is mainly obtained through the initWebApplicationContext method and create a WebApplicationContext object. In the initWebApplicationContext method, two main things are done: one is to get the Spring context, and the other is to put the Spring context into the ServletContext, and the key is: WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE. So how do you get the context of Spring? It is to obtain the path of Spring configured in web.xml. CONFIG_LOCATION_PARM is actually a string constant, which is the following configured Spring listener in web.xml:
<context-param> <param-name>contextConfigLocation</param-name> <!--CONFIG_LOCATION_PARM is contextConfigLocation--> <param-value>classpath:beans.xml</param-value> </context-param>
So it is obvious that you get beans.xml through the path configured in web.xml, then load this configuration file and instantiate the bean.
Now that we know that after Spring loads the configuration file and puts it in the ServletContext, we can go here and get it directly!
//@Component // Listener is a component of the web layer. It is instantiated by tomcat, not Spring. Can't be put in Spring public class InitDataListener implements ServletContextListener { private ProductService productService = null; @Override public void contextDestroyed(ServletContextEvent event) { // TODO Auto-generated method stub } @Override public void contextInitialized(ServletContextEvent event) { // Get business logic class query product information// Solution 2: When the project is started, the Spring configuration file is loaded through the Spring listener and stored in the ServletContext. We just need to obtain it in the ServletContext. ApplicationContext context = (ApplicationContext) event.getServletContext() .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); productService = (ProductService) context.getBean("productService"); System.out.println(productService); } } In this way, we can get the instantiated object of the producerService. This method is good, but the parameters in the getAttribute are too long. I don’t know if the programmer’s forehead was clipped at that time. I guess he couldn’t think of other more suitable names~
4. Loading through the tool class provided by Spring <br />Maybe the big guys who developed Spring also realized that the name of this parameter was too long, so they provided a method class that can load the configuration file:
public class InitDataListener implements ServletContextListener { private ProductService productService = null; @Override public void contextDestroyed(ServletContextEvent event) { // TODO Auto-generated method stub } @Override public void contextInitialized(ServletContextEvent event) { // Get business logic class query product information WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); productService = (ProductService) context.getBean("productService"); System.out.println(productService); } } In fact, the getWebApplicationContext method here just encapsulates the above method. Let’s look at the source code of this method:
public static WebApplicationContext getWebApplicationContext(ServletContext sc) { return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); }This is more convenient for programmers to call, that's all...so we generally use the third method to get Spring's configuration file, thereby obtaining the corresponding instantiated bean.
Original link: http://blog.csdn.net/eson_15/article/details/51373937
The above is the solution to the iPhone 6splus WeChat crash. I hope it will be helpful to everyone. I also hope that everyone will support Wulin.com and pay more attention to more exciting content on Wulin.com.