zoukankan      html  css  js  c++  java
  • SprignBoot中的一些小知识点(一)

    1、@Configuration 的 proxyBeanMethods 属性,意思是不是代理bean的方法。

    proxyBeanMethods 属性默认为true,则为代理bean,且代理bean中的方法。所以,无论获取多少遍该配置类或者该配置类中的方法,均为单例。
    若为 false,则Spring容器中不会保留该配置类的dailiduixi9ang,每次获取的配置类对象不同,方法也不同。
    
      总结:配置类组件之间无依赖关系,用 false,加速容器启动过程,减少判断。
    
           配置类组件之间有依赖关系,用true,方法被调用得到之前的单实例组件。

    2、@Conditional   条件加载绑定

             条件装配的魅力,SpringBoot底层按需加载机制用到很多condition系列的注解,可以去详细看一下。

    3、@ConfigurationProperties + @Component (加在容器中 并 进行属性绑定)

               加载配置文件中的属性到实体类。

    4、SpringBoot 的自动配置原理:

          @SpringBootApplication  分为:

    @SpringBootConfiguration :我是一个配置类。
    @EnableAutoConfiguration :利用Register 给容器导入一系列组件,将指定包下的所有组件导入,也就是根目录下的所有的类。其下有一个功能,就是加载 所有 META-INF/spring.factories  下的所有组件,另外得益于Conditional 注解,按需加载的              机制,很好的限制了SpringBoot容器中的组件个数,举例来说:当引入了某个jar后 才会加载该组件。 
    @ComponentScan :标识作为一个组件。

    5、SpringBoot会在底层配置好所有组件,但是如果用户想自己配置了,则以用户配置的优先。

    6、yaml 配置文件加入debug=true ,启动项目时会打印哪些组件生效(positive),那些组件不生效(negative)

    7、Springboot 关于整合SpringMVC的一些概念知识

    1、静态资源路径概念:
    默认:只要静态资源放在以下类路径下:/static or /public or /resource or /MET-INF/resources 下,访问静态资源时只需 在当前项目根路径 / + 静态资源文件名 即可
    原理: 静态映射配置的 /**
    请求进来,先去找Controller 试下能不能处理,不能处理的请求进一步交给静态资源处理器,静态资源再找不到直接404
    2、修改静态资源前缀:web项目一般都会有未登录不让访问动态资源的拦截器校验,为了不让拦截器一起把静态资源也拦截掉,就统一给静态资源添加一个例如 /res 前缀,然后在拦截器中放开 /res 路径访问权限,这样就可以实现只拦截动态资源访问,不拦截静态资源。
    实现以上功能只需在yaml中配置 spring.mvc.static-path-pattern: /res/**
    添加/res配置后不需要在静态资源访问目录加/res
    3、限制静态资源存储目录:开发中,我们如果想要把所有的静态资源全部放到 /haha 目录下,只需在yaml中添加 spring.resources.static-locations: classpath:/haha/  即可 或者数组 spring.resources.static-locations: [classpath:/haha/,classpath:/hehe/]

    8、SpringBoot 集成SpringMVC 底层静态资源配置

    SpringMVC配置类主要集中在:WebMvcAutoConfiguration 这个配置类中,

    目录:/org/springframework/boot/spring-boot-autoconfigure/2.4.5/spring-boot-autoconfigure-2.4.5.jar!/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.class
    我们进入WebMvcAutoConfiguration类中的一个静态内部类:WebMvcAutoConfigurationAdapter ,注意到该内部类只有一个构造方法:

    public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
                this.mvcProperties = mvcProperties;
                this.beanFactory = beanFactory;
                this.messageConvertersProvider = messageConvertersProvider;
                this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
                this.dispatcherServletPath = dispatcherServletPath;
                this.servletRegistrations = servletRegistrations;
                this.mvcProperties.checkConfiguration();
            }

    约定的规则就是:配置类如果只有一个有参构造器,那么构造方法中所有参数的值都会从容器中寻找。 

    WebProperties webProperties :在内部类的 @EnableConfigurationProperties 注解上已经绑定 WebProperties 到容器中,直接在容器中获取即可 

    WebMvcProperties mvcProperties:同上一个

     ListableBeanFactory beanFactory:相当于Spring的bean 工厂 

    ObjectProvider<HttpMessageConverters> messageConvertersProvider:找到所有httpMessageConverter

    ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider:资源处理器的自定义器

    ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations:给用注册sevlet、Filter,后来再说

     好的,我们继续在类中寻找与静态资源配置相关的方法:

    // addResourceHandlers 顾名思义:添加静态资源处理器
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
                super.addResourceHandlers(registry);
                if (!this.resourceProperties.isAddMappings()) {
                    logger.debug("Default resource handling disabled");
                } else {
                    ServletContext servletContext = this.getServletContext();
                    this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                    this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                        if (servletContext != null) {
                            registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
                        }
    
                    });
                }
            }

    所以:所有静态资源处理规则就在这个方法了,不难看出第一个判断,this.resourceProperties.isAddMappings() ,获取了容器中 resourceProperties 的addMapping 这个 布尔类型的数据

    为true 就往下加载静态配置类的规则。

         配置了webjars的访问路径(前端的一些js引用也达成了jar供项目引入 )

         包括设置静态资源缓存配置时间配置

          包括配置静态资源默认的路径  

                    this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                        if (servletContext != null) {
                            registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
                        }
    
                    });
    
    // 点进 this.mvcProperties.getStaticPathPattern(),很容易看到配置了如下几个默认的四个静态资源路径
    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
     

    为fale 就直接 在degug级别打印日志 说:默认资源处理器失效,仅用所有静态资源规则,不再允许访问所有的静态资源。

    注:(这个 addMapping 就是 配置文件中 spring.web.resources.add-mappings 对应的值)

     我们再看一下,SpringBoot 底层封装SpringMVC如何处理欢迎页静态资源的。

    继续在  WebMvcAutoConfiguration 这个类中 找到  welcomePageHandlerMapping ,顾名思义 这是欢迎页处理器映射,

            @Bean
            public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
                WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
                welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
                welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
                return welcomePageHandlerMapping;
            }

    我们进入 new WelcomePageHandlerMapping(..) 这个有参构造:

        WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
            //第一行判断代码的意思就是:当欢迎页存在 且 静态资源路径为  /** 的时候,才会跳转欢迎页面
            if (welcomePage != null && "/**".equals(staticPathPattern)) {
                logger.info("Adding welcome page: " + welcomePage);
                this.setRootViewName("forward:index.html");
            } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
                //否则,他会去找Controller 找一下,谁能处理
                logger.info("Adding welcome page template: index");
                this.setRootViewName("index");
            }
    
        }
  • 相关阅读:
    简单跟跟spring源码
    java.lang.UnsupportedOperationException mybatis
    通过自定义注解校验后台接口请求参数
    java的修饰符 public --> protected -->default --> private
    Ubuntu安装google-chrome
    git设置core.autocrlf
    时钟时间,系统cpu时间,用户cpu时间
    推荐-Everything搜索工具
    Ubuntu no such file or directory
    centos安装docker
  • 原文地址:https://www.cnblogs.com/dk1024/p/14794305.html
Copyright © 2011-2022 走看看