SpringBoot学习——运行原理学习及自定义Starter pom

SpringBoot学习——运行原理学习及自定义Starter pom

项目下载

项目下载

运行原理

SpringBoot最大的特点就是提供了很多默认的配置,Spring4.x提供了基于条件来配置Bean的能力,SpringBoot就是通过这一原理来实现的。
那么我们如何来实现一个自定义的starter呢

自定义Starter pom

新建一个maven项目

参考SpringBoot学习——SpringBoot入门HelloWorld

总目录结构

修改pom.xml,添加相关依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.pzr</groupId>
    <artifactId>spring-boot-starter-pzrhello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 引用依赖的父包 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
    <!-- 依赖包 -->
    <dependencies>
        <!-- spring boot 自动配置需要的包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <!-- spring boot需要的包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>
</project>

添加属性配置类

package com.pzr.spring_boot_stater_pzrhello;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 属性配置类
 * @author pzr
 *
 */
@ConfigurationProperties(prefix="hello")
public class HelloServiceProperties {
    private static final String MSG = "world";
    private String msg = MSG;
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }

}

代码说明:
使用@ConfigurationProperties注解来设置前缀,在application中通过hello.msg=来设置,若不设置,默认为hello.msg=world。

添加判断依据类

package com.pzr.spring_boot_stater_pzrhello;

/**
 * 判断依据类
 * @author pzr
 *
 */
public class HelloService {
    private String msg;

    public String sayHello(){
        return "Hello "+msg;
    }

    public String getMsg() {
        return msg;
    }

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

}

代码说明
通过此类来调用msg,进行打印。

添加自动配置类

package com.pzr.spring_boot_stater_pzrhello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 自动配置类
 * @author pzr
 *
 */
@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class)
@ConditionalOnClass(HelloService.class)
@ConditionalOnProperty(prefix="hello",value="enabled",matchIfMissing=true)
public class HelloServiceAutoConfiguration {
    @Autowired
    private HelloServiceProperties helloServiceProperties;

    @Bean
    public HelloService helloService(){
        HelloService helloService = new HelloService();
        helloService.setMsg(helloServiceProperties.getMsg());
        return helloService;
    }



}

代码说明
1. @Configuration:使用该注解来说明该类是配置类,等价于xml中的beans
2. @EnableConfigurationProperties(HelloServiceProperties.class):开启属性注入,对注解配置Bean的支持
3. @ConditionalOnClass(HelloService.class):条件注解,当类路径下有指定的类的条件下。
4. @ConditionalOnProperty(prefix=”hello”,value=”enabled”,matchIfMissing=true):条件注解,指定的属性是否有指定的值。当设置hello=enabled,如果没有设置则默认为true,即为条件符合。假如我们将matchIfMissing设置为false,则当设置hello=enabled时,条件为false,则不会将该Bean加载进容器类,当使用@Autowired注入HelloService时会报错。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.pzr.spring_boot_stater_pzrhello.HelloService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
  1. @Autowired:将属性配置类注入进来。
  2. @Bean:使用Java配置的方式来配置这个类,等价于xml中的bean。
  3. @ConditionalOnMissingBean(HelloService.class):容器中没有这个Bean时,新建这个Bean。

注册配置

在src/main/resource下新建META-INFO/spring.factories文件。该文件可在spring-boot-1.5.1.RELEASE\spring-boot-autoconfigure\src\main\resources\META-INF下找到。
个人的只需要设置如下即可:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.pzr.spring_boot_stater_pzrhello.HelloServiceAutoConfiguration

如果有多个,逗号分隔即可,如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration

同项目下使用

添加主方法

在当前项目下,添加MainApplication.java,用于测试之前写的starter是否成功

package com.pzr.spring_boot_stater_pzrhello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@SpringBootApplication
public class MainApplication {

    @Autowired
    HelloService helloService;

    @RequestMapping("/")
    public String index(){
        return helloService.sayHello();
    }

    public static void main(String[] args){
        SpringApplication.run(MainApplication.class, args);
    }
}

添加application.properties

在src/main/resources下添加application.properties配置文件

debug=true
hello.msg=1231231

debug是为了看到启动日志
hello.msg是我们自定义的打印内容

启动项目

结果如下:

打包使用

将项目打包并发到本地库

右键项目–>Run as–>Maven build..

输入clean install发到本地库

新建一个maven项目

修改pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>HelloConsumer</groupId>
    <artifactId>HelloConsumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 引用依赖的父包 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
    <!--maven的插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- 打成jar包后所执行的主函数 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>com.pzr.consumer.test.OfficialDemo</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <!-- 依赖包 -->
    <dependencies>
        <!-- spring boot需要的包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.pzr</groupId>
            <artifactId>spring-boot-starter-pzrhello</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>
</project>

其中spring-boot-starter-pzrhello是我们刚刚打的包

添加MainApplication.java文件

package com.pzr.springbootautoconfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.pzr.spring_boot_stater_pzrhello.HelloService;


@RestController
@ComponentScan(basePackages={"com.pzr"})  
@SpringBootApplication
public class MainApplication {

    @Autowired
    HelloService helloService;

    @RequestMapping("/")
    public String index(){
        return helloService.sayHello();
    }

    public static void main(String[] args){
        SpringApplication.run(MainApplication.class, args);
    }
}

注意:如果不设置@ComponentScan(basePackages={“com.pzr”}) ,则会扫描不到com.pzr.spring_boot_stater_pzrhello下的bean,只会默认扫描所在类包下的所有目录。

添加application.properties

debug=true
hello.msg=pzrmsg

运行查看效果


从结果可以看出虽然spring-boot-starter-pzrhello包里也有application.properties文件,但是最终使用的是新项目中的application.properties文件的设置。

问题

  1. 无论我设不设置@ConditionalOnMissingBean(HelloService.class),bean都会加载。
  2. 无论我在不在spring.factories中添加HelloServiceAutoConfiguration,配置都会生效。
  3. 在jar包使用时,如果不设置@ComponentScan(basePackages={“com.pzr”})将会报错,找不到bean。给注解是设置扫描位置的,可设置多个。
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.pzr.spring_boot_stater_pzrhello.HelloService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

最近将会继续学习springboot,如果有大神能看到这篇笔记,希望能不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-贫寒豌豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值