Резюме
После прочтения этой статьи у вас будут следующие очки знаний:
- Какую автоматическую настройку нам помогает сделать SpringBoot?
- Как мы можем взять на себя автоматическую настройку SpringBoot
- Методы регистрации Servlet, Filter и Listener
серия SpringBoot:Заметки об исследовании Spring Boot
Автоматическая настройка SpringBoot
1. Классы автоматической конфигурации хранятся вspring-boot-autoconfigure-1.4.2.RELEASE.jarвниз
org.springframework.boot.autoconfigureпод дорожкой;
2.Настройка в application.propertiesdebug=true
После запуска контейнера видно, что автоматическая настройка инициализации сервера выглядит следующим образом:
- DispatcherServletAutoConfiguration
регистрorg.springframework.web.servlet.DispatcherServlet - EmbeddedServletContainerAutoConfiguration
Зарегистрируйте тип контейнера, если он существует в пути к классам.org.apache.catalina.startup.Tomcat, контейнер Tomcat будет зарегистрирован - ErrorMvcAutoConfiguration
Зарегистрировать обработчик исключений - HttpEncodingAutoConfiguration
Зарегистрировать фильтр кодирования http - HttpMessageConvertersAutoConfiguration
Зарегистрируйте процессор json или xml - JacksonAutoConfiguration
Зарегистрировать парсер объектов json - JmxAutoConfiguration
регистрJMXуправляющий деламиИнтеграция JMX с Spring
Spring регистрирует MBeans в JMX с помощью аннотаций аннотаций для отслеживания текущего состояния Java. - MultipartAutoConfiguration
Регистрация процессоров передачи файлов - ServerPropertiesAutoConfiguration
Он используется для инициализации связанных с контейнером свойств конфигурации, таких как адрес службы, порт и contextPath, а также для инициализации уникальных свойств каждого контейнера в соответствии с текущим типом контейнера, таких как maxThreads, uriEncoding и т. д. Tomcat. Соответствующий класс свойств:ServerProperties; - WebClientAutoConfiguration
Зарегистрировать RestTemplate - WebMvcAutoConfiguration
Зарегистрируйте связанные с SpringMvc процессоры, такие как ResourceResolver, RequestMappingHandlerAdapter, ExceptionHandlerExceptionResolver, ViewResolver, LocaleResolver и т. д. - WebSocketAutoConfiguration
Зарегистрируйте процессоры, связанные с webSocket, и зарегистрируйте разные процессоры в соответствии с типом контейнера.
3. Если к зависимостям добавляются зависимости других функций, SpringBoot также реализует автоматическую адаптацию этих функций.Например, если мы добавим функцию JPA базы данных, это позволитJpaRepositoriesAutoConfigurationфункция автоматической настройки. Содержание базы данных будет представлено позже.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
иллюстрировать
Для каждого класса конфигурации AutoConfiguration можно увидеть следующие аннотации.На основе этих аннотаций можно определить порядок инициализации этих AutoConfigurations:
- @AutoConfigureOrder(-2147483648): чем меньше число, тем первым инициализируется
- @AutoConfigureAfter({EmbeddedServletContainerAutoConfiguration.class}): загрузка после инициализации указанного класса конфигурации
- @AutoConfigureBefore({WebMvcAutoConfiguration.class}): загружать до инициализации указанного класса конфигурации.
Возьмите на себя автоматическую настройку SpringBoot
мы представили@SpringBootApplicationЭта аннотация, поскольку она содержит@EnableAutoConfigurationа также@ComponentScanAnnotation может автоматически сканировать связанные классы автоконфигурации для реализации функции автоконфигурации.
Как было сказано выше, SpringBoot по умолчанию инициализирует множество автоматических конфигураций.Некоторые из этих конфигураций могут не использоваться в проекте.Как их удалить?
Удалите ненужные классы автоконфигурации
Например, нам не нужно включать автоматическую настройку webSocket и JMX, нам нужно@SpringBootApplicationуказано в этой аннотацииexcludeАтрибуты
@SpringBootApplication(exclude = {WebSocketAutoConfiguration.class,JmxAutoConfiguration.class})
public class SpringBootWebDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebDemoApplication.class, args);
}
}
Явно укажите, какую автоконфигурацию необходимо включить
мы можем удалить@SpringBootApplicationАннотировать, использовать вместо@Конфигурация, @Импорт, @Сканирование компонентовобратите внимание, в@ImportЯвно укажите, какие автоконфигурации необходимо включить в аннотациях.
//@SpringBootApplication(exclude = {WebSocketAutoConfiguration.class,JmxAutoConfiguration.class})
@Configuration
@Import({
DispatcherServletAutoConfiguration.class,
EmbeddedServletContainerAutoConfiguration.class,
ErrorMvcAutoConfiguration.class,
HttpEncodingAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
JacksonAutoConfiguration.class,
MultipartAutoConfiguration.class,
ServerPropertiesAutoConfiguration.class,
WebMvcAutoConfiguration.class
})
@ComponentScan
public class SpringBootWebDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebDemoApplication.class, args);
}
}
проиллюстрировать:
- Здесь рекомендуется первый метод:@SpringBootApplication(exclude={});
- На самом деле включение функции автоматической настройки по умолчанию повлияет только на время запуска проекта, поэтому нет особой необходимости отключать определенную функцию автоматической настройки;
- В некоторых случаях, например, когда проекту требуется несколько источников данных, проект будет содержать несколько bean-компонентов DataSource, потому чтоDataSourceAutoConfigurationАвтоконфигурация может привязывать только один источник данных.В настоящее время, если в Spring зарегистрировано несколько компонентов DataSource, будет выдано исключение.
1. В это время вы можете использовать для удаленияDataSourceAutoConfigurationПуть;
2. Или вы можете объявить его в Bean-компоненте источника данных.@PrimaryАннотация, указав его как основной источник данных, затемDataSourceAutoConfigurationзагрузит только указанный@PrimaryОсновной источник данных аннотации, чтобы вы могли пользоваться преимуществами автоматической настройки SpringBoot.
Возьмите на себя автоматическую настройку WebMvc
Для веб-проекта важнее всего управление, связанное с Mvc, SpringBoot черезWebMvcAutoConfigurationЧтобы завершить автоматическую настройку, связанную с Mvc. Если вы хотите полностью взять на себя автоматическую настройку WebMvc, вы можете создать аннотацию в проекте@EnableWebMvcкласс конфигурации, например:
package com.example;
import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.util.Properties;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example", useDefaultFilters = false, includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class})
})
public class MvcConfig extends WebMvcConfigurationSupport {
private static final Logger logger = Logger
.getLogger(MvcConfig.class);
/**
* 描述 : <注册视图处理器>. <br>
*<p>
<使用方法说明>
</p>
* @return
*/
@Bean
public ViewResolver viewResolver() {
logger.info("ViewResolver");
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/jsp/function/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/**
* 描述 : <注册消息资源处理器>. <br>
*<p>
<使用方法说明>
</p>
* @return
*/
@Bean
public MessageSource messageSource() {
logger.info("MessageSource");
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("config.messages.messages");
return messageSource;
}
/**
* 描述 : <注册servlet适配器>. <br>
*<p>
<只需要在自定义的servlet上用@Controller("映射路径")标注即可>
</p>
* @return
*/
@Bean
public HandlerAdapter servletHandlerAdapter(){
logger.info("HandlerAdapter");
return new SimpleServletHandlerAdapter();
}
/**
* 描述 : <本地化拦截器>. <br>
*<p>
<使用方法说明>
</p>
* @return
*/
@Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
logger.info("LocaleChangeInterceptor");
return new LocaleChangeInterceptor();
}
/**
* 描述 : <基于cookie的本地化资源处理器>. <br>
*<p>
<使用方法说明>
</p>
* @return
*/
@Bean(name="localeResolver")
public CookieLocaleResolver cookieLocaleResolver(){
logger.info("CookieLocaleResolver");
return new CookieLocaleResolver();
}
/**
* 描述 : <添加拦截器>. <br>
*<p>
<使用方法说明>
</p>
* @param registry
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
logger.info("addInterceptors start");
registry.addInterceptor(localeChangeInterceptor());
logger.info("addInterceptors end");
}
/**
* 描述 : <资源访问处理器>. <br>
*<p>
<可以在jsp中使用/static/**的方式访问/WEB-INF/static/下的内容>
</p>
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.info("addResourceHandlers");
registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/static/");
}
/**
* 描述 : <文件上传处理器>. <br>
*<p>
<使用方法说明>
</p>
* @return
*/
@Bean(name="multipartResolver")
public CommonsMultipartResolver commonsMultipartResolver(){
logger.info("CommonsMultipartResolver");
return new CommonsMultipartResolver();
}
/**
* 描述 : <异常处理器>. <br>
*<p>
<系统运行时遇到指定的异常将会跳转到指定的页面>
</p>
* @return
*/
@Bean(name="exceptionResolver")
public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
logger.info("CP_SimpleMappingExceptionResolver");
SimpleMappingExceptionResolver simpleMappingExceptionResolver= new SimpleMappingExceptionResolver();
simpleMappingExceptionResolver.setDefaultErrorView("common_error");
simpleMappingExceptionResolver.setExceptionAttribute("exception");
Properties properties = new Properties();
properties.setProperty("java.lang.RuntimeException", "common_error");
simpleMappingExceptionResolver.setExceptionMappings(properties);
return simpleMappingExceptionResolver;
}
}
На этом этапе, когда вы запустите проект в режиме отладки, вы увидитеWebMvcAutoConfigurationОн не настраивается автоматически, что указывает на то, что мы определяем его сами.MvcConfig
полностью взял на себя автоматическую настройку по умолчанию, потому чтоWebMvcAutoConfigurationЕсть условная аннотация:
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
И в нашем случаеMvcConfig
Это класс реализации WebMvcConfigurationSupport, при добавлении@EnableWebMvcАннотация также импортирует класс реализации WebMvcConfigurationSupport: DelegatingWebMvcConfiguration.
,такMvcConfig
Наследовать WebMvcConfigurationSupport не обязательно, но нам удобно кодировать.
Ссылаться на:Нулевая конфигурация SpringMVC4 — конфигурация веб-контекста [MvcConfig]
Если вы хотите продолжать использоватьWebMvcAutoConfigurationАвтоматическая конфигурация, но нужно только изменить или добавить некоторую конфигурацию в MVC, мы можем создать класс конфигурации и наследовать от абстрактного класса.WebMvcConfigurerAdapter, мы можем зарегистрировать собственный контроллер, реализуя методы абстрактного класса.
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
public WebMvcConfigurerAdapter() {
}
public void configurePathMatch(PathMatchConfigurer configurer) {
}
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
public void addFormatters(FormatterRegistry registry) {
}
public void addInterceptors(InterceptorRegistry registry) {
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
public void addCorsMappings(CorsRegistry registry) {
}
public void addViewControllers(ViewControllerRegistry registry) {
}
public void configureViewResolvers(ViewResolverRegistry registry) {
}
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
}
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
}
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
}
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
}
public Validator getValidator() {
return null;
}
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
}
Например, мы можем добавить контроллер перехода вида следующим образом:
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/demo/123").setViewName("/demo");
}
}
Методы регистрации Servlet, Filter и Listener
1. Если это проект военного пакета, мы можем зарегистрировать Servlet, Filter и Listener дляWebApplicationInitializerв классе реализации
@Order(1)
public class CommonInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
//Log4jConfigListener
servletContext.setInitParameter("log4jConfigLocation", "classpath:log4j.properties");
servletContext.addListener(Log4jConfigListener.class);
//OpenSessionInViewFilter
OpenSessionInViewFilter hibernateSessionInViewFilter = new OpenSessionInViewFilter();
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter(
"hibernateFilter", hibernateSessionInViewFilter);
filterRegistration.addMappingForUrlPatterns(
EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "/");
//DemoServlet
DemoServlet demoServlet = new DemoServlet();
ServletRegistration.Dynamic dynamic = servletContext.addServlet(
"demoServlet", demoServlet);
dynamic.setLoadOnStartup(2);
dynamic.addMapping("/demo_servlet");
}
}
2. Если это метод развертывания пакета jar, вы можете зарегистрировать его для любого@Configurationв классе конфигурации
@Configuration
public class WebConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean_demo1(){
return new ServletRegistrationBean(new DemoServlet(),"/demo-servlet1");
}
@Bean
public ServletRegistrationBean servletRegistrationBean_demo2(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.addUrlMappings("/demo-servlet2");
servletRegistrationBean.setServlet(new DemoServlet2());
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new OpenSessionInViewFilter());
Set<String> set = new HashSet<String>();
set.add("/");
filterRegistrationBean.setUrlPatterns(set);
return filterRegistrationBean;
}
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean();
servletListenerRegistrationBean.setListener(new Log4jConfigListener());
servletListenerRegistrationBean.addInitParameter("log4jConfigLocation","classpath:log4j.properties");
return servletListenerRegistrationBean;
}
}
Суммировать
Опишите автоматическую настройку SpringBoot одним предложением:Это набор классов конфигурации Spring, которые реализуют регистрацию Bean-компонентов на основе условных аннотаций.