[笔记迁移][Spring Boot]入门[1]

15 篇文章 0 订阅

1. What is Spring Boot?

SpringBoot -> JavaEE 一栈式 解决方案以简化独立的、产品级别的Spring应用开发

“约定大于配置”思想的实现

2. Why Spring Boot?

(1)快速 创建独立运行的Spring项目以及与主流框架集成;
(2)使用 嵌入式Servlet容器 ,应用无需打成war包;
(3)场景启动器 starters自动依赖与版本控制
(4)大量的 自动配置,简化开发,轻松覆盖默认值;
(5)无需配置xml ,无代码生成,开箱即用;
(6)准生产环境的运行时应用监控;
(7)与云计算天然集成;

3. 什么是微服务?

(1) 2014, Martin Fowler
(2) 架构风格:
   <1>一个应用应该是一组小型服务,通过Http的方式进行互通;
   <2>每一个功能元素最终都是一个 可动态组合,独立替换,独立升级的软件单元
MicroService
(3) Spring “三步走”
SpringSteps

4. Getting start
4.1 环境约束
  1. jdk 1.8:Spring Boot推荐 jdk1.7以上
  2. Maven 3.x
    <!-- settings.xml -->
    <profile>
              <id>jdk-1.8</id>
              <activation>
                   <activeByDefault>true</activeByDefault>
                   <jdk>1.8</jdk>
              </activation>
              <properties>
                   <maven.compiler.source>1.8</maven.compiler.source>
                   <maven.compiler.target>1.8</maven.compiler.target>               					  <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
              </properties>
    </profile>
    
  3. IntelliJ IDEA 2017:配置Maven
  4. Spring Boot 1.5.9 REALEASE
4.2 Hello World

功能:浏览器发送hello请求,服务器接收请求并处理,响应HelloWorld字符串

  1. IntelliJ IDEA 创建Maven工程(打包选jar),坐标如下
    HelloWorldMaven
  2. 导入Spring Boot相关依赖
    	<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>
    
  3. 编写用于启动应用的主程序
    /**
     * @SpringBootApplication 来标注一个主程序类,说明这是一个Srping Boot应用
     */
    @SpringBootApplication
    public class HelloWorldMainApplication {
        public static void main(String[] args) {
            //启动Spring应用
            SpringApplication.run(HelloWorldMainApplication.class,args);
        }
    }
    
  4. 编写相关Controller
    @Controller
    public class HelloController {
        @RequestMapping("/hello")
        @ResponseBody
        public String hello(){
            return  "hello,world";
        }
    }
    
  5. 直接运行主程序测试
  6. 简化打包,部署
    <!-- 给pom.xml添加一个打包此插件,该插件可以将应用打包成一个可执行的jar包;-->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    MavenPackage
    打包成一个jar,使用java -jar命令运行此jar即可部署。 打包时已内嵌Tomcat
4.3 Hello World原理剖析
  1. pom.xml中的父项目

    	<parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.9.RELEASE</version>
        </parent>
    
    	<!--pom.xml中父项目的父项目,真正管理SpringBoot应用中所有依赖的版本 -->
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-dependencies</artifactId>
    		<version>1.5.9.RELEASE</version>
    		<relativePath>../../spring-boot-dependencies</relativePath>
    	</parent>
    

    Spring Boot的 版本仲裁 中心:以后导入依赖不需要指定版本;
    当然,没有在spring-boot-dependencies里面管理的依赖必须写版本号;

  2. 启动器

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

    spring-boot-starter-web -> spring-boot-starter-xxx :
    Spring Boot对所有功能场景进行抽取,形成一个个starter(场景启动器),只需要在项目中引入需求的starter,对应场景的所需组件的依赖都会自动导入 ,换句话说,要用什么功能,就引什么场景的starter。当然,依赖的版本是受父项目版本仲裁的。

  3. 主程序的入口,@SpringBootApplication(核心注解)
    @SpringBootApplication 标注在某个类上,表示该类为当前Spring Boot应用的主配置类 ,Spring Boot应该运行该类的 main() 来启动Spring Boot应用

    【@SpringBootApplication底层上是一系列注解的组合】

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    //----------
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    public @interface SpringBootApplication
    

    其中有两个关键注解:@SpringBootConfiguration / @EnableAutoConfiguration

    (1) @SpringBootConfiguration
      <1> 标注在某个类上,表示该类是SpringBoot的一个配置类;
      <2> 使用Spring的底层注解 @Configuration 可以达到相同的效果;
      <3> 配置类===配置文件,配置类也是容器的一个组件@Component

    (2) @EnableAutoConfiguration
      <1> 表示自动开启配置功能,之前需要手动配置的东西,Spring Boot进行自动化配置
      <2> @EnableAutoConfiguration也是一系列注解的组合

    @AutoConfigurationPackage
    
    @Import({EnableAutoConfigurationImportSelector.class})
    
    public @interface EnableAutoConfiguration
    

    其中包含两个关键要素:@AutoConfigurationPackage / EnableAutoConfigurationImportSelector

    要素说明
    @AutoConfigurationPackage自动配置包,相当于使用Spring底层注解@Import(AutoConfigurationPackages.class),给容器导入一个组件AutoConfigurationPackages


    AutoConfigurationPackages的作用:方法调用register(registry, new PackageImport(metadata).getPackageName()) ,底层反射找到@SpringBootApplication的anotation metadata,将主配置类所在包及其子包里面所有的组件扫描并注入Spring容器中
    AutoConfigurationPackages
    EnableAutoConfigurationImportSelector底层调用其父类AutoConfigurationImportSelector#selectImports(AnnotationMetadata),将所有需要导入的组件以 全类名 的方式返回(组成String[]),给容器导入非常多的自动配置类(xxxAutoConfiguration)即向容器中自动导入当前场景需要的所有组件的自动配置类,并由这些类完成对相应组件自动配置(避免之前手写xml配置功能组件)
    selectImports
    SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader),启动时自动从 类路径下META-INF/spring.factories中获取EnableAutoConfiguration指定的值
    JavaEE整体的整合方案和自动配置都在spring-boot-autoconfigure\1.5.9.RELEASE\spring-boot-autoconfigure-1.5.9.RELEASE.jar
       //AutoConfigurationImportSelector的核心方法
       public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            try {
                AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                //重要的源码,见下块代码区
                List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                configurations = this.sort(configurations, autoConfigurationMetadata);
                Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = this.filter(configurations, autoConfigurationMetadata);
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return (String[])configurations.toArray(new String[configurations.size()]);
            } catch (IOException var6) {
                throw new IllegalStateException(var6);
            }
        }
    }
    
    	//getCandidateConfigurations的源码
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        	//传递了两个参数,第一个点进去是EnableAutoConfiguration.class,第二个点进去是classLoader,点进方法见下方代码块
        	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;
    }
    
    	//loadFactoryNames的源码
        public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
    
        try {
            //这里就指明了获取列表的位置,所有jar包类路径下META-INF/spring.factories
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            ArrayList result = new ArrayList();
    
            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                //遍历url,转换为一个Properties,拿到factoryClassName指定的value,这个factoryClassName就是传过来EnableAutoConfiguration.class类名
                Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                String factoryClassNames = properties.getProperty(factoryClassName);
                //加入到结果集合中
                result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
            }
    		//结果就是要交给容器的所有组件的全类名列表
            return result;
        } catch (IOException var8) {
            throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8);
        }
    }
    
5. 使用Spring Initializer快速创建Spring Boot项目

(1) File -> New Project -> Spring Initializer -> Maven定制坐标等信息 -> 启动器startes选择 -> 向导联网创建

(2) 默认生成的SpringBoot项目特点:
   <1> 主程序已经自动生成,只需要编写业务逻辑即可
   <2> resources 文件夹中目录结构
static:保存所有的静态资源,如js,css,imgs…
templates:保存所有的模板页面。注意:Spring Boot默认jar包使用嵌入式Tomcat,默认不支持JSP页面,但可以使用“模板引擎”如freemarker,thymeleaf
application.properties:Spring Boot应用的配置文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值