27

『互联网架构』软件架构-springboot自定义视图和自定义Starter(90)

 4 years ago
source link: https://www.tuicool.com/articles/v2aU3qn
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

自定义视图和自定义Starter做成统一配置,方便使用。

Ur67zyq.png!web

(一)自定义视图映射

在项目开发过程中,经常会涉及页面跳转问题,而且这个页面跳转没有任何业务逻辑过程,只是单纯的路由过程 ( 例如:点击一个按钮跳转到一个页面 ) 。

@RequestMapping("/testmvc")
 public String view(){
    return "abc";
 }

现在只需要这样统一写,此类必须在启动类所在包或者子包中

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/testmvc").setViewName("/abc");
    }
}

页面:abc.flt 或者 abc.html

访问http://localhost:8081/testmvc 即可访问到这个abc.flt文件]

<html>
<body>
    hello
</body>
</html>

(二)自定义Starter

在我们学习SpringBoot时都已经了解到starter是SpringBoot的核心组成部分,SpringBoot为我们提供了尽可能完善的封装,提供了一系列的自动化配置的starter插件,我们在使用spring-boot-starter-web时只需要在pom.xml配置文件内添加依赖就可以了,我们之前传统方式则是需要添加很多相关SpringMVC配置文件。而spring-boot-starter-web为我们提供了几乎所有的默认配置,很好的降低了使用框架时的复杂度。因此在使用xx.starter时你就不用考虑该怎么配置,即便是有一些必要的配置在application.properties配置文件内对应配置就可以了,那好,为什么我在application.properties配置对应属性后xx.starter就可以获取到并作出处理呢?下面我们带着这个疑问来编写我们自定义的starter让我们深入了解SpringBoot。

  • 创建自己的starter项目

    >创建【普通maven项目】,修改pom.xml,增加自动配置依赖

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>1.5.10.RELEASE</version>
    </dependency>

我们这个starter并不做其他复杂逻辑的编写,所以这里的依赖只是添加了spring-boot-autoconfigure,实战开发时可以添加任意依赖到项目中。

  • 配置映射参数实体

    >starter是如何读取application.properties或者application.yml配置文件内需要的配置参数的呢?那么接下来我们就看看如何可以获取自定义的配置信息。

    SpringBoot在处理这种事情上早就已经考虑到了,所以提供了一个注解@ConfigurationProperties,该注解可以完成将application.properties配置文件内的有规则的配置参数映射到实体内的field内,不过需要提供setter方法,自定义配置参数实体代码如下所示

@ConfigurationProperties(prefix = "hello")
public class HelloProperties{
    private String msg = "test";
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

````

>在上面代码中,@ConfigurationProperties注解内我们使用到了属性preffix,该属性配置了读取参数的前缀,根据上面的实体属性对应配置文件内的配置则是hello.msg,当然我们提供了默认值,配置文件内不进行配置时则是使用默认值。

* 编写自定义业务
> 自定义starter提供一个Service,并且提供一个名为sayHello的方法用于返回我们配置的msg内容。

``` java
public class HelloService{
    private String msg;

    public String sayHello(){
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

Service内的代码比较简单,根据属性参数进行返回格式化后的字符串。

接下来我们开始编写自动配置,这一块是starter的核心部分,配置该部分后在启动项目时才会自动加载配置,当然其中有很多细节性质的配置。

  • 实现自动化配置

    >自动化配置其实只是提供实体bean的验证以及初始

@Configuration//开启配置
@EnableConfigurationProperties(HelloProperties.class)//开启使用映射实体对象
@ConditionalOnClass(HelloService.class)//存在HelloService时初始化该配置类
@ConditionalOnProperty//存在对应配置信息时初始化该配置类
        (
                prefix = "hello",//存在配置前缀hello
                value = "enabled",//开启
                matchIfMissing = true//缺失检查
        )
public class HelloAutoConfiguration{
    //application.properties配置文件映射前缀实体对象
    @Autowired
    private HelloProperties helloProperties;
    /**
     * 根据条件判断不存在HelloService时初始化新bean到SpringIoc
     * @return
     */
    @Bean//创建HelloService实体bean
    @ConditionalOnMissingBean(HelloService.class)//缺失HelloService实体bean时,初始化HelloService并添加到SpringIoc
    public HelloService helloService(){
        System.out.println(">>>The HelloService Not Found,Execute Create New Bean.");
        HelloService helloService = new HelloService();
        helloService.setMsg(helloProperties.getMsg());//设置消息内容
        return helloService;
    }
}

自动化配置代码中有很多我们之前没有用到的注解配置。

1. @Configuration:这个配置就不用多做解释了,我们一直在使用

2. @EnableConfigurationProperties:这是一个开启使用配置参数的注解,value值就是我们配置实体参数映射的ClassType,将配置实体作为配置来源。

SpringBoot内置条件注解

有关@ConditionalOnXxx相关的注解这里要系统的说下,因为这个是我们配置的关键,根据名称我们可以理解为具有Xxx条件,当然它实际的意义也是如此,条件注解是一个系列,注解都是元注解@Conditional演变而来的,根据不用的条件对应创建以上的具体条件注解。需要了解SpringBoot运作原理后才可以完成后续编码。

1. @ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件

2. @ConditionalOnClass:当SpringIoc容器内存在指定Class的条件

3. @ConditionalOnExpression:基于SpEL表达式作为判断条件

4. @ConditionalOnJava:基于JVM版本作为判断条件

5. @ConditionalOnJndi:在JNDI存在时查找指定的位置

6. @ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件

7. @ConditionalOnMissingClass:当SpringIoc容器内不存在指定Class的条件

8. @ConditionalOnNotWebApplication:当前项目不是Web项目的条件

9. @ConditionalOnProperty:指定的属性是否有指定的值

10. @ConditionalOnResource:类路径是否有指定的值

11. @ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean

12. @ConditionalOnWebApplication:当前项目是Web项目的条件

  • Starter自动化运作原理

    > 在注解@SpringBootApplication上存在一个开启自动化配置的注解@EnableAutoConfiguration来完成自动化配置

@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

    String[] excludeName() default {};
}

在@EnableAutoConfiguration注解内使用到了@import注解来完成导入配置的功能,而EnableAutoConfigurationImportSelector内部则是使用了SpringFactoriesLoader.loadFactoryNames方法进行扫描具有META-INF/spring.factories文件的jar包。我们可以先来看下spring-boot-autoconfigure包内的spring.factories文件内容

B7R7naZ.png!web

可以看到配置的结构形式是Key=>Value形式,多个Value时使用,隔开,那我们在自定义starter内也可以使用这种形式来完成,我们的目的是为了完成自动化配置,所以我们这里Key则是需要使用org.springframework.boot.autoconfigure.EnableAutoConfiguration

  • 自定义spring.factories

    >我们在src/main/resource目录下创建META-INF目录,并在目录内添加文件spring.factories

#配置自定义Starter的自动化配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.HelloAutoConfiguration

都目前为止我们的自定义starter已经配置完成。下面我们需要新建一个SpringBoot项目来测试我们的自动化配置是否已经生效。

  • 创建SpringBoot测试项目

    > 创建spring boot项目,在pom文件中增加自定义的starter依赖

<dependency>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-starter-hello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

controller引入自定义starter中的service调用业务

Mfua6vi.png!web

  • 运行测试

    > 在运行项目之前,我们打开application.properties配置文件开启debug模式,查看自动化配置的输出日志,配置内容如下所示:

#显示debug日志信息
debug=true

接下来我们启动项目,在控制台查找是否存在我们的HelloAutoConfiguration日志输出在控制台可以看到我们的自定义starter的自动化配置已经生效了,并且根据@ConditionalOnMissingBean(HelloService.class)做出了条件注入HelloService实体bean到SpringIoc容器内。

PS:application.properties配置文件为什么可以作为统一配置入口,为什么配置后可以被对应starter所使用。

百度未收录

>>原创文章,欢迎转载。转载请注明:转载自IT人故事会,谢谢!

>>原文链接地址:上一篇:

已是最新文章


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK