springboot篇--初探学习1

2023-12-13 04:50:55

一.回顾Spring

  • Spring是一个开源框架,2003 年兴起的一个轻量级的Java 开发框架,作者:Rod Johnson
  • Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。

? ? ? ? 1.1Spring是如何简化Java开发的

????????基于POJO的轻量级和最小侵入性编程,所有东西都是bean;

????????通过IOC,依赖注入(DI)和面向接口实现松耦合;

????????基于切面(AOP)和惯例进行声明式编程;

????????通过切面和模版减少样式代码,RedisTemplate,xxxTemplate;

二、什么是springboot

1.SpringBoot是由Pivotal团队提供的全新框架。

其设计目的是

1.用来简化Spring应用搭建和开发过程的一种框架;

2.整个Spring技术栈的一个大整合;

3.J2EE开发的一站式解决方案;

2.优缺点:

优点:

Create stand-alone Spring applications
创建独立Spring应用
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌web服务器
Provide opinionated ‘starter’ dependencies to simplify your build configuration
自动starter依赖,简化构建配置
Automatically configure Spring and 3rd party libraries whenever possible
自动配置Spring以及第三方功能
Provide production-ready features such as metrics, health checks, and externalized configuration
提供生产级别的监控、健康检查及外部化配置
Absolutely no code generation and no requirement for XML configuration
无代码生成、无需编写XML

SpringBoot是整合Spring技术栈的一站式框架

SpringBoot是简化Spring技术栈的快速开发脚手架

?缺点:

  • 迭代快,需要时刻关注变化

  • 封装太深,内部原理复杂,不容易精通

三。依赖包

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!-- 这个插件,可以将应用打包成一个可执行的jar包;-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

三、彩蛋

1.在resource下新建banner.txt,放入自喜欢的图像。

四、初探springboot的自动装配。

?1.pom.xml

spring-boot-starter-parent
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
  • 其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件!

点击进去发现还有一个父依赖---spring-boot-dependencies?

这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;?

所以:以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了?

启动器 spring-boot-starter?
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

springboot-boot-starter-xxx:就是spring-boot的场景启动器?

SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter .

2.主启动类?

1.@SpringBootApplication

?

点击进入:

?2.重要的注解分析:
@SpringBootConfiguration 
    @Configuration  spring 配置类
        @Component  说明这也是一个spring的组件

@EnableAutoConfiguration 自动导入配置。
    @AutoConfigurationPackage 自动导入配置包
        @Import(AutoConfigurationPackages.Registrar.class)  自动配置包注册。
    @Import({AutoConfigurationImportSelector.class})    自动导入选择
@ComponentScan
SpringBootConfiguration 作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

?@Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;里面的@Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!

EnableAutoConfiguration:以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

@AutoConfigurationPackage :自动配置包,

@import?:Spring底层注解@import , 给容器中导入一个组件

Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器.

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件

@ComponentScan这个注解在Spring中很重要 ,它对应XML配置中的元素。 作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

3.源码分析:AutoConfigurationImportSelector

AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?

1.点击进入:------发现:getCandidateConfigurations方法(获得候选的配置)

// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    //这里的getSpringFactoriesLoaderFactoryClass()方法
    //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

2.发现调用了 ---loadFactoryNames? 跟进去。

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    //这里它又调用了 loadSpringFactories 方法
    return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
3.继续点击查看 loadSpringFactories 方法
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    //获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
    if (result != null) {
        return result;
    } else {
        try {
            //去获取一个资源 "META-INF/spring.factories"
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            LinkedMultiValueMap result = new LinkedMultiValueMap();

            //将读取到的资源遍历,封装成为一个Properties
            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();

                while(var6.hasNext()) {
                    Entry<?, ?> entry = (Entry)var6.next();
                    String factoryClassName = ((String)entry.getKey()).trim();
                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    int var10 = var9.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        String factoryName = var9[var11];
                        result.add(factoryClassName, factoryName.trim());
                    }
                }
            }

            cache.put(classLoader, result);
            return result;
        } catch (IOException var13) {
            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
        }
    }
}
4.发现:META-INF/spring.factories 全局搜索。

?随便点击一个进去:

?

可以看到这些一个个的都是JavaConfig配置类,而且都注入了一些Bean

自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。
?

3.总结?

SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;
?

五、其他拓展。

1.SpringApplication.run分析

2. 配置文件优先级。

3.配置文件理解。

?理解截图:比如配置文件配置了如下:
spring:
????activemq:
????????broker-url:


那么肯定代表有一个ActiveMQProperties 有broker-url方法
对应的org/springframework/boot/spring-boot-autoconfigure/2.6.13
/spring-boot-autoconfigure-2.6.13.jar!/META-INF/spring.factories
配置文件中肯定有一个注入:org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration

其中肯定有@EnableConfigurationProperties({ActiveMQProperties.class, JmsProperties.class})

文章来源:https://blog.csdn.net/he123456lei/article/details/134846659
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。