项目下载
SpringBoot最大的特点就是提供了很多默认的配置,Spring4.x提供了基于条件来配置Bean的能力,SpringBoot就是通过这一原理来实现的。
那么我们如何来实现一个自定义的starter呢
参考SpringBoot学习——SpringBoot入门HelloWorld
<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.0modelVersion>
<groupId>com.pzrgroupId>
<artifactId>spring-boot-starter-pzrhelloartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.1.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-autoconfigureartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
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)}
在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);
}
}
在src/main/resources下添加application.properties配置文件
debug=true
hello.msg=1231231
debug是为了看到启动日志
hello.msg是我们自定义的打印内容
结果如下:
右键项目–>Run as–>Maven build..
输入clean install发到本地库
<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.0modelVersion>
<groupId>HelloConsumergroupId>
<artifactId>HelloConsumerartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.1.RELEASEversion>
parent>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-jar-pluginartifactId>
<configuration>
<archive>
<manifest>
<addClasspath>trueaddClasspath>
<mainClass>com.pzr.consumer.test.OfficialDemomainClass>
manifest>
archive>
configuration>
plugin>
plugins>
build>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.pzrgroupId>
<artifactId>spring-boot-starter-pzrhelloartifactId>
<version>0.0.1-SNAPSHOTversion>
dependency>
dependencies>
project>
其中spring-boot-starter-pzrhello是我们刚刚打的包
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,只会默认扫描所在类包下的所有目录。
debug=true
hello.msg=pzrmsg
从结果可以看出虽然spring-boot-starter-pzrhello包里也有application.properties文件,但是最终使用的是新项目中的application.properties文件的设置。
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,如果有大神能看到这篇笔记,希望能不吝赐教。