我们在使用SpringBoot 项目时,引入一个springboot start依赖,只需要很少的代码,或者不用任何代码就能直接使用默认配置,再也不用那些繁琐的配置了,感觉特别神奇。我们自己也动手写一个start.
一、新建一个 Start 的 Maven 项目
- pom 文件如下
org.springframework.boot spring-boot-dependencies 2.1.0.RELEASE pom import org.springframework.boot spring-boot-autoconfigure compile org.projectlombok lombok 1.18.6 true provided org.springframework.boot spring-boot-starter-test test
- spring-boot-autoconfigure springboot 自动配置的核心依赖
- spring-boot-starter-test 测试包
- lombok 省去 getter/setter 等简化代码
- 演示代码
DemoService:
public interface DemoService { String getMessage(); Integer getCode();}
DemoServiceImpl:
public class DemoServiceImpl implements DemoService { @Override public String getMessage() { return "Hello!"; } @Override public Integer getCode() { return 123; }}
DemoAutoConfiguration:
@Configurationpublic class DemoAutoConfiguration { @Bean @ConditionalOnMissingBean(DemoService.class) public DemoService demoService() { return new DemoServiceImpl(); }}
- @Configuration 标注该类为一个配置类
- ConditionalOnMissingBean(DemoService.class) 条件注解
spingboot 的自动注解主要还是用这些条件注解来实现的。请查看之前的文章:
- 让springboot 识别自动自动配置的代码
需要在resources下新建文件META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.jiuxian.DemoAutoConfiguration
SpringBoot 中的注解 @EnableAutoConfiguration 在项目启动的时候会通过 SpringFactoriesLoader.loadFactoryNames 方法获取 spring.factories 文件下的配置类
- 测试类
- 首先需要再包下建 Application run 的main 方法
@SpringBootApplicationpublic class StartDemoApplication { public static void main(String[] args) { SpringApplication.run(StartDemoApplication.class, args); }}
- 测试类
@RunWith(SpringRunner.class)@SpringBootTestpublic class StartDemoApplicationTests { @Resource private DemoService demoService; @Test public void test() { String message = demoService.getMessage(); System.out.println(message); Assert.assertEquals("Hello!", message); Integer code = demoService.getCode(); System.out.println(code); Assert.assertEquals(123, (int) code); }}
如果没有 StartDemoApplication 这个类则测试类启动的时候会报 @SpringBootApplication 找不到错误
二、新建 springboot 项目引入刚写的start项目
- service
@Servicepublic class TestService { @Resource private DemoService demoService; public void message() { System.out.println("code:" + demoService.getCode()); System.out.println("message:" + demoService.getMessage()); }}
- 测试
@Resource private TestService testService; @Test public void test() { testService.message(); }
结果:
code:123message:Hello!
- 重写DemoService方法
@Servicepublic class DemoServiceImpl implements DemoService { @Override public String getMessage() { return "Hello!"; } @Override public Integer getCode() { return 123; }}
- 测试结果
code:123message:Hello!
之所以这样的结果,是因为在start项目中的DemoService 实现类中有一个 @ConditionalOnMissingBean(DemoService.class) 的注解,如果不存在则使用默认的