spring-mvc注解方式加载配置

spring-mvc注解方式加载配置

一、web.xml方式

1.web.xml配置内容

spring使用3.2.4版本

如下为配置的web.xml文件

<context-param>
    <param-name>contextClass</param-name>
    <param-value>
        org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    </param-value>
</context-param>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>org.springsource.cloudfoundry.mvc.services.config.ServicesConfiguration</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <servlet-name>appServlet</servlet-name>
</filter-mapping>

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>org.springsource.cloudfoundry.mvc.web.WebMvcConfiguration</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

2.spring监听

这个监听是加载非spring-mvc注解的注解配置(如@Controller)

  1. 启动spring监听
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
  1. 监听使用的参数:

    (1)contextClass:

    ​ spring使用的加载配置类(ApplicationContext),这里显式写出使用AnnotationConfigWebApplicationContext注解方式加载配置。如果没有填写默认使用WebApplicationContext

    (2)contextConfigLocation:

    ​ 配置注解类(org.springsource.cloudfoundry.mvc.services.config.ServicesConfiguration),多个类使用","逗号分隔。 如:org.springsource.cloudfoundry.mvc.services.config.ServicesConfiguration1,org.springsource.cloudfoundry.mvc.services.config.ServicesConfiguration2。具体根据实际项目里的配置填写

<context-param>
​    <param-name>contextClass</param-name>
​    <param-value>
​        org.springframework.web.context.support.AnnotationConfigWebApplicationContext
​    </param-value>
</context-param>

<context-param>
​    <param-name>contextConfigLocation</param-name>
     <param-value>org.springsource.cloudfoundry.mvc.services.config.ServicesConfiguration</param-value>
</context-param>

如下为源码

/**
	 * Return the WebApplicationContext implementation class to use, either the
	 * default XmlWebApplicationContext or a custom context class if specified.
	 * @param servletContext current servlet context
	 * @return the WebApplicationContext implementation class to use
	 * @see #CONTEXT_CLASS_PARAM
	 * @see org.springframework.web.context.support.XmlWebApplicationContext
	 */
	protected Class<?> determineContextClass(ServletContext servletContext) {
		String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
		if (contextClassName != null) {
			try {
				return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
			}
			catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load custom context class [" + contextClassName + "]", ex);
			}
		}
		else {
			contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
			try {
				return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
			}
			catch (ClassNotFoundException ex) {
				throw new ApplicationContextException(
						"Failed to load default context class [" + contextClassName + "]", ex);
			}
		}
	}

3.spring-mvc注解配置

和spring监听相同的参数

contextClass和contextConfigLocation,只是用来注解mvc相关注解。contextConfigLocation有多个文件的话使用","分隔

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>org.springsource.cloudfoundry.mvc.web.WebMvcConfiguration</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

4.相关的注解类

WebMvcConfiguration

@Configuration
@EnableWebMvc
@ComponentScan
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
    InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
    internalResourceViewResolver.setViewClass(JstlView.class);
    internalResourceViewResolver.setPrefix("/WEB-INF/views/");
    internalResourceViewResolver.setSuffix(".jsp");
    return internalResourceViewResolver;
}

@Bean
public MessageSource messageSource() {
    String[] baseNames = "messages".split(",");
    ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
    resourceBundleMessageSource.setBasenames(baseNames);
    return resourceBundleMessageSource;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/web/**").addResourceLocations("/web/");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("customers");
}

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

}

ServicesConfiguration

@Configuration
@PropertySource("/config.properties")
@EnableCaching
@EnableTransactionManagement
@Import({CloudFoundryDataSourceConfiguration.class, LocalDataSourceConfiguration.class})
@ComponentScan(basePackageClasses = {CustomerService.class})
public class ServicesConfiguration {

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) throws Exception {
    return new JpaTransactionManager(entityManagerFactory);
}

}

二、纯注解配置

spring使用5.0.4.RELEASE版本

通过继承AbstractAnnotationConfigDispatcherServletInitializer来实现,继承这个类在容器初始化是会被检测调用。

MvcShowcaseAppInitializer

/**

- Initialize the Servlet container. This class is detected by the Servlet

- container on startup.
  */
  public class MvcShowcaseAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

  @Override
  protected Class<?>[] getRootConfigClasses() {
  ​	return new Class[] { RootConfig.class };
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
  ​	return new Class[] { WebMvcConfig.class };
  }

  @Override
  protected String[] getServletMappings() {
  ​	return new String[] { "/" };
  }

  @Override
  protected Filter[] getServletFilters() {
  ​	return new Filter[] { new DelegatingFilterProxy("csrfFilter") };
  }

}

RootConfig

// Root Context: defines shared resources visible to all other web components

@Configuration
public class RootConfig {

​```
// CSRF protection. Here we only include the CsrfFilter instead of all of Spring Security.
// See http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#csrf
// for more information on Spring Security's CSRF protection

@Bean
public CsrfFilter csrfFilter() {
	return new CsrfFilter(new HttpSessionCsrfTokenRepository());
}

// Provides automatic CSRF token inclusion when using Spring MVC Form tags or Thymeleaf.
// See http://localhost:8080/#forms and form.jsp for examples

@Bean
public RequestDataValueProcessor requestDataValueProcessor() {
	return new CsrfRequestDataValueProcessor();
}
​```

}

WebMvcConfig

// DispatcherServlet context: defines Spring MVC infrastructure
// and web application components

@Configuration
@ComponentScan(basePackages = "org.springframework.samples.mvc")
@EnableWebMvc
@EnableScheduling
public class WebMvcConfig implements WebMvcConfigurer {

​```
@Override
public void addFormatters(FormatterRegistry registry) {
	registry.addFormatterForFieldAnnotation(new MaskFormatAnnotationFormatterFactory());
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
	resolvers.add(new CustomArgumentResolver());
}

// Handle HTTP GET requests for /resources/** by efficiently serving
// static resources under ${webappRoot}/resources/

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
	registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
	registry.addViewController("/").setViewName("home");
}

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
	registry.jsp("/WEB-INF/views/", ".jsp");
}

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
	UrlPathHelper pathHelper = new UrlPathHelper();
	pathHelper.setRemoveSemicolonContent(false); // For @MatrixVariable's
	configurer.setUrlPathHelper(pathHelper);
}

@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
	configurer.setDefaultTimeout(3000);
	configurer.registerCallableInterceptors(new TimeoutCallableProcessingInterceptor());
}

@Bean
public MultipartResolver multipartResolver() {
	return new CommonsMultipartResolver();
}
​```

}

为什么AbstractAnnotationConfigDispatcherServletInitializer就会被容器加载?因为这个类实现了WebApplicationInitializer接口。SpringServletContainerInitializer中实现了ServletContainerInitializer接口,并使用@HandlesTypes,在容器初始化时就会加载实现WebApplicationInitializer接口的类

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

猜你喜欢

转载自blog.csdn.net/lanwp5302/article/details/85256104