Integrated Junit:
Example:
(1) Import dependent
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.5.RELEASE</version> <scope>test</scope> </dependency>
It should be noted that the version of spring test should be consistent with the previously introduced version of spring context
(2) Create test class SpringJunitTest
import Service.UserService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringJunitTest { @Autowired private UserService userService; @Test public void test1() { userService.say(); } }
@RunWith(SpringJUnit4ClassRunner.class) is used to let the test execute in the Spring container environment
@ContextConfiguration is used to specify xml configuration files or configuration classes, as follows
@ContextConfiguration(locations = "classpath:applicationContext.xml") @ContextConfiguration(classes = SpringConfiguration.class)
analysis:
After Spring integrates Junit, unit testing can be carried out in the above way. The program automatically creates a Spring container. We only need to inject the bean s to be tested through @ Autowired annotation
Integrated Web environment:
Example:
(1) Create the Web layer and write the UserServlet class
package Web; import Config.SpringConfiguration; import Service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class); UserService userService = app.getBean(UserService.class); userService.say(); } }
Override the doGet method to create a Spring container, get the Service layer object userService, and call its say method
(2) Configuring servlet mapping in web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>UserServlet</servlet-name> <servlet-class>Web.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserServlet</servlet-name> <url-pattern>/userServlet</url-pattern> </servlet-mapping> </web-app>
Map the access path to the corresponding servlet
(3) Test by visiting localhost:8080/userService in the browser
Start Tomcat and access it in the browser localhost:8080/userService
The console successfully outputs the results
Disadvantages analysis:
When there are many interfaces in the Web layer, a Spring container needs to be created in the processing method of each servlet, resulting in the configuration file / class being loaded many times and the Spring container being created many times, affecting the performance
Solution:
In the Web project, use the ServletContextListener to listen to the start of the Web application. When the Web application starts, create an ApplicationContext object and store it in the servletContext field, so as to access the ApplicationContext object anywhere
(1) Create listener ContextLoaderListener
package Listener; import Config.SpringConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class ContextLoaderListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class); sce.getServletContext().setAttribute("app", app); } @Override public void contextDestroyed(ServletContextEvent sce) { } }
The listener class implements the ServletContextListener interface and overrides the contextInitialized method, which will be called when the Web application starts. The Spring container is created in the method and stored in the servletContext domain
(2) Configuring listeners in web.xml
<listener> <listener-class>Listener.ContextLoaderListener</listener-class> </listener>
(3) In the doGet method of UserServlet class, obtain the ApplicationContext object through the servletContext field
package Web; import Service.UserService; import org.springframework.context.ApplicationContext; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app"); UserService userService = app.getBean(UserService.class); userService.say(); } }
There are two ways to obtain ServletContext objects
ServletContext servletContext = req.getServletContext(); ServletContext servletContext = this.getServletContext();
Profile decoupling:
For the creation of ApplicationContext in the listener, you need to specify the configuration file. You can configure the global parameter in web.xml and specify the configuration file as the global parameter to realize the decoupling of the configuration file
(1) Configuring global parameters in web.xml
<context-param> <param-name>contextConfigLocation</param-name> <param-value>applicationContext.xml</param-value> </context-param>
(2) Get the parameters in the listener and create the ApplicationContext object
public void contextInitialized(ServletContextEvent sce) { ServletContext servletContext = sce.getServletContext(); String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation"); ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation); sce.getServletContext().setAttribute("app", app); }
The global parameters can be obtained through the getInitParameter method of the ServletContext object
Get ApplicationContext optimization
(1) Write the tool class WebApplicationContextUtils
package Util; import org.springframework.context.ApplicationContext; import javax.servlet.ServletContext; public class WebApplicationContextUtils { public static ApplicationContext getWebApplicationContext(ServletContext servletContext) { return (ApplicationContext) servletContext.getAttribute("app"); } }
For the static method getWebApplicationContext, just pass in the ServletContext to return the ApplicationContext object
(2) Modify the access to ApplicationContext in the doGet method
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext); UserService userService = app.getBean(UserService.class); userService.say(); }
Directly call the static method of WebApplicationContextUtils to obtain the ApplicationContext object
Use Spring tools to obtain ApplicationContext objects:
For the created above ContextLoaderListener, WebApplicationContextUtils and Spring provide exactly the same functions and are encapsulated in the Spring web package
(1) Import dependent
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.1.5.RELEASE</version> </dependency>
Note that the version of Spring web needs to be the same as that of other Spring packages imported earlier
(2) Configuring listener and profile global parameters in web.xml
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
The configuration file path here needs to be added with classpath
(3) Get the ApplicationContext object using WebApplicationContextUtils
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext); UserService userService = app.getBean(UserService.class); userService.say(); }