Java架构师—构建聚合工程并整合SpringBoot

前言

       项目分层设计的原则;构建聚合工程;整合SpringBoot;SpringBoot自动装配机制。


文章目录

  • 前言
  • 一、构建聚合工程
    • 1.1 项目分层设计原则
    • 1.2 构建聚合工程
      • 1.2.1 创建父级工程
      • 1.2.2 创建子工程
  • 二、聚合工程整合SpringBoot
    • 2.1 SpringBoot依赖。
    • 2.2 设置资源属性
    • 2.3 引入依赖dependency
    • 2.4 创建application.yml文件
    • 2.5 创建Application启动类
  • 三、SpringBoot自动装配简述
    • 3.1 SpringBoot为什么可以做到几乎零配置?
  • 总结


一、构建聚合工程

1.1 项目分层设计原则

  • 项目拆分与聚合
    Java架构师—构建聚合工程并整合SpringBoot_第1张图片
  • Maven聚合项目
    Java架构师—构建聚合工程并整合SpringBoot_第2张图片

1.2 构建聚合工程

  1. 聚合工程里可以分为顶级项目(顶级工程、父工程)与子工程,这两者的关系其实就是父子继承的关系。子工程在manen里称之为模块(module),模块之间是平级,是可以相互依赖的。
  2. 子模块可以使用顶级工程里所有的资源(依赖),子模块之间要使用资源,必须构建依赖(构建关系)。
  3. 一个顶级工程可以由多个不同的子工程共同组合而成。

1.2.1 创建父级工程

       步骤:Create New Project→Maven。
Java架构师—构建聚合工程并整合SpringBoot_第3张图片
       选择Maven,点击Next。
Java架构师—构建聚合工程并整合SpringBoot_第4张图片
       填写GroupId、ArtifactId、Version,点击Next。
Java架构师—构建聚合工程并整合SpringBoot_第5张图片
       填写Project name、Project_location,点击Finish。
Java架构师—构建聚合工程并整合SpringBoot_第6张图片
       父级工程创建完成。
Java架构师—构建聚合工程并整合SpringBoot_第7张图片

1.2.2 创建子工程

       步骤:选中父级工程目录,New→Module。
Java架构师—构建聚合工程并整合SpringBoot_第8张图片
       依旧选择Maven。
Java架构师—构建聚合工程并整合SpringBoot_第9张图片
       填写GroupId、ArtifactId、Version,点击Next。
Java架构师—构建聚合工程并整合SpringBoot_第10张图片
       填写Module name,点击Finish。
Java架构师—构建聚合工程并整合SpringBoot_第11张图片
       运行之前需要安装,Maven的安装:点击工程,选择工程,选择Lifecycle,双击install。控制台出现[INFO] BUILD SUCCESS,即代表安装成功。

  • packing的三种方式:jar、war、pom;
  • pom文件中父级工程打包方式选择pom;
  • module的packing选择jar。默认打包方式为 jar。

二、聚合工程整合SpringBoot

2.1 SpringBoot依赖。

       pom文件中引入依赖parent。SringBoot的父级依赖,引入parent,证明此项目就是一个SpringBoot项目。

	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.1.5.RELEASEversion>
		<relativePath />
	parent>

2.2 设置资源属性

       pom文件中设置资源属性。

	<properties>
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
		<java.version>1.8java.version>
	properties>

2.3 引入依赖dependency

       pom文件中引入依赖dependency。

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-starter-loggingartifactId>
                exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
            
        
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-aopartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>
    dependencies>

2.4 创建application.yml文件

       在resource目录下创建application.yml文件

2.5 创建Application启动类

       创建Class文件Application,用于启动项目。在类名引入注解@SpringBootApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
// 扫描 mybatis 通用 mapper 所在的包
@MapperScan(basePackages = "com.imooc.mapper")
// 扫描所有包以及相关组件包
@ComponentScan(basePackages = {"com.imooc", "org.n3r.idworker"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  • 控制器层注解:@Controller和**@RestController**;@RestController默认返回Json对象。
  • @getMapping(“路由”):用于方法,表明是get请求。

三、SpringBoot自动装配简述

3.1 SpringBoot为什么可以做到几乎零配置?

       ConfigurableApplicationContext 使用默认的设置,创建了一个SpringApplication对象。同时调用了SpringApplication对象的run方法,返回一个容器的上下文对象ApplicationContext。
       默认的设置在@SpringBootApplication注解中。

    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class[]{primarySource}, args);
    }

       @ComponentScan容器启动时,会默认扫描启动类所在的当前包及子包下的类。

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;

@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 {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

       @SpringBootConfiguration中@Configuration,表明SpringBootConfiguration是一个容器。

package org.springframework.boot;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

       @EnableAutoConfiguration自动装载容器。

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

       @Import用于导入容器Configuration。

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    Class<?>[] value();
}

       AutoConfigurationImportSelector.class自动装配导入选择器。
       重载的方法selectImports中,getAutoConfigurationEntry用于获得自动装配的实体。

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

       getCandidateConfigurations获取备用的默认的配置。

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

       在META-INF下生成spring.factories文件。

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        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;
    }

       META-INF/spring.factories中存放着所有的XXConfiguration。
       例如:

  • 内置Tomcat:org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
  • 集成Sping MVC:
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\

Java架构师—构建聚合工程并整合SpringBoot_第12张图片

总结

项目分层设计的原则;构建聚合工程;整合SpringBoot;SpringBoot自动装配机制。

你可能感兴趣的:(Java架构师之路,java,架构,spring,spring,boot,maven)