Analysis on the Implementation Process of Theme Switching in Spring

When I first came into contact with Theme, I couldn't understand it at all, the execution logic of the code. This is an ominous sign. After reading it a few times and scratching it repeatedly, the code execution logic has begun to emerge.

Preliminary work:

  1. Maven dependencies
  2. servlet context
  3. Project file structure
  4. Code link click to open the link charpter3/theme

  • Maven dependencies
	    <dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.0.5.RELEASE</version>
		</dependency>
	</dependencies>

Note: The spring-webmvc project must introduce spring-mvc dependencies, but the problem is that there are transitive dependencies, that is, spring-mvc depends on spring-core, spring-web, spring-context, and spring-beans. So these dependencies should also be introduced together.


  • servlet context

Content in web.xml

        <servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>*.mvc</url-pattern>
	</servlet-mapping>

Content in springmvc-servlet.xml

<context:component-scan base-package="com.wiley.beginningspring.ch3" />
    <context:annotation-config />
    <mvc:annotation-driven />
 
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"/>

    <bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
        <property name="defaultThemeName" value="dark" />
    </bean>

    <mvc:interceptors>
        <bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
            <property name="paramName" value="theme"/>
        </bean>
    </mvc:interceptors>


  • Project file structure


Ok, so far, the pre-work is complete. Now let's decipher the code:

What happens when we enter http://localhost:8080/form.mvc in the URL address bar? This is an important point for beginners.

First, http://localhost:8080/form.mvc will be converted into an http request, and the http request will first reach the front-end controller, where the front-end controller is the org.springframework.web.servlet that appears in web.xml. DispatcherServlet. All requests cannot escape the clutches of DispatcherServlet. The form.mvc in the URL is a pattern matching field, and its identification and matching work corresponds to <url-pattern>*.mvc</url-pattern>, and all requests ending with .mvc are eventually imported into org.springframework.web. servlet.DispatcherServlet. The front controller greets the mapping handler and says: Hey, mapping handler, come here and see which controller is responsible for the form.mvc request. The mapping processor, in a pinch, is in charge of the user of the FormController home. Why? look:

@Controller
public class FormController {

    @RequestMapping(value = "/form")
    public ModelAndView user() {
        return new ModelAndView("form", "user", new User());
    }

    @RequestMapping(value = "/result")
    public ModelAndView processUser(User user) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("u", user);
        modelAndView.setViewName("result");

        return modelAndView;
    }
}

User wears a hat called /form on his head, that's the guy, big brother, yell at him and let him work. So the front controller handed over the form.mvc request to user() for processing, and user() stored the processed data model in a place that everyone can access: ModelAndView, and user() also explained, next The object of one step work is form.jsp. After the DispatcherServlet listened to the report of user(), it called the view parser and said: You, do this, do this, do it well, hit! So the parser tries to get the data from ModelAndView, assemble the data into the specified grid on the form.jsp page, and then it crosses. After the DispatcherServlet listens to the work of the view parser, it will hand over the aftermath to the browser. After the browser finishes rendering, you can see that your request has been answered.

Here comes the problem: You are hypocritical and think the current page is too bright. Or too dark. You want to be able to change it at will, so you pay a reasonable price, some genius programmer solves the problem for you, you are not satisfied, and you want to know how your world suddenly changes from when you click on a hyperlink Day has turned into night. You can't figure it out. You said, if you hear the word in the morning, you can die in the evening. What price, said the genius programmer who met your needs? ...

Lecture: Transformation of Theme

First take a look at springmvc-servlet.xml

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"/>

    <bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
        <property name="defaultThemeName" value="dark" />
    </bean>

    <mvc:interceptors>
        <bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
            <property name="paramName" value="theme"/>
        </bean>
    </mvc:interceptors>
 
 

The three core mechanisms of the theme architecture are themeSource, themeResolver, and themeChangeInterceptor.

What is themeSource? Specifically read the properties file in the path, such as dark.properties, the format of the file is in the form of key-value pairs, such as style=css/dark.css

What does themeResolver do? Of course, the theme file is processed and analyzed.

What about themeChangeInterceptor? The effect of switching themes.

The division of labor among the three is different. themeSource gets a lot of theme resources, themeChangeInterceptor selects theme resources, and themeResolver processes theme resources. How exactly did it go? Look at a piece of code involved in theme switching in the form.jsp code:

<head>
    <title>Spring MVC Themes</title>
    <!-- key value defined in properties file -->
    <link rel="stylesheet" href="<spring:theme code="style"/>" type="text/css" />
</head>
<body>
Theme :
<a href="?theme=light">Light</a> - <a href="?theme=dark">Dark</a>
<br/>

First look at <link rel="stylesheet" href="<spring:theme code="style"/>" type="text/css" />, this paragraph obviously introduces theme resources. But the problem is that I didn't see the theme resource package. I imported .css and .js files before, but I clearly wrote the resource path and the resource name to be imported. But this, can't see it. This will involve themeSource, because the resource is found by him, and you can only use it if he finds the resource. The question is themeSource, how did he find the resource? This has to do with the time when Pangu created the world. Here, just know that when the themeSource is created, it will look for the properties file and load the resource. It's like I stopped understanding, but what is this lump of <spring:theme code="style"/>? He is a resource. It's a list of resources. why? I have already said that the loaded resources exist in the form of key-value pairs, and the style at this time is like the list name. Because the content in the two properties files is style=css/dark.css and style=css/light.css. Obviously, there are two elements in the list at this point [css/dark.css, css/light.css]. By default css/dark.css is used. why? Because springmvc-servlet.xml says:

<bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver">
        <property name="defaultThemeName" value="dark" />
    </bean>

Theme switching occurs when you click on any of <a href="?theme=light">Light</a> - <a href="?theme=dark">Dark</a> on the page. How is this done? For example, if you click on <a href="?theme=light">Light</a>, this is a hyperlink! Where does it link to? People only gave one? , How can it make sense! In fact, by default, themeChangeInterceptor is responsible for processing, which means jumping to themeChangeInterceptor. Why? What do you want to do when you click <a href="?theme=light">Light</a>? Switch themes! themeChangeInterceptor's vocation is for switching. Let's see how themeChangeInterceptor handles it.

    <mvc:interceptors>
        <bean id="themeChangeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
            <property name="paramName" value="theme"/>
        </bean>
    </mvc:interceptors>  

I don't understand, do you? If you can understand it, it's a hell of a lot. I'm so smart, I was stunned when I saw this for the first time. It's like this: what does it mean when you click a hyperlink? Means you made an http request. The http request will save the parameter theme=light you requested to the request. themeChangeInterceptor receives the http request, and also gets the request. Then, above <mvc:interceptors>...</mvc:interceptors>, there is such a paragraph between <property name="paramName" value="theme"/>, that is to say, theme will be assigned as a value to paramName, okay, what is the theme? theme is the key in the key-value pair! themeChangeInterceptor got theme=light through quest, and got theme through paramName, so what is he going to do next? Of course, it is to get the value light in the key-value pair. What do you do after you get the light? Of course, the light.css in the style list is obtained according to light, and then it is naturally handed over to themeResolver for parsing. After the themeResolver is parsed, it is handed over to the browser for rendering. Finally, the theme effect after switching is selected in front of you.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325725284&siteId=291194637