为了何更好的理解该篇内容,请先阅读Spring Boot 原理解析—入口SpringApplication。
我们知道在使用Spring Boot时,Spring会自动加载Spring Boot中启动类包下以及其子包下的带注解的类,本篇不会讲述是如何加载注解类的,因为这是属于Spring的内容,我们只讲述为什么会根据启动类加载子包下的带注解的类。在讲解Spring Boot源码之前我们先看一下Spring中包的扫描方式一种是@ComponentScan("cn.org.microservice.spring.ioc.annotation")注解,另一种则是以XML的方式配置:
<context:component-scan base-package="cn.org.microservice.spring.ioc.annotation"/>
如果我们不使用XMl而使用@ComponentScan,但是在注解中不配置然任何包,也就是说直接在@Configuration注解的泪伤注解@ComponentScan,代码如下所示:
package cn.org.microservice.spring.ioc.annotation;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class ConfigrationBean {
}
然后在其子包下创建几个Bean,如下所示,我们在其子包下创建了三个Bean类,为了方便我们只创建类,没有创建接口。
package cn.org.microservice.spring.ioc.annotation.bean.service;
import org.springframework.stereotype.Service;
@Service
public class ServiceBean {
}
package cn.org.microservice.spring.ioc.annotation.bean;
import org.springframework.stereotype.Component;
@Component
public class BeanA {
}
package cn.org.microservice.spring.ioc.annotation.bean1;
import org.springframework.stereotype.Component;
@Component
public class Bean2 {
}
然后我们使用测试类测试,然后输出容器中注册的Bean的名称。
public class AnnotationTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConfigrationBean.class);
for(String beanName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanName);
}
}
}
//一下为输出内容
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
configrationBean
beanA
serviceBean
bean2
通过输出我们看到容器中居然注册其子包下的注解类,但是实际上上我们并没有告诉容器去注册cn.org.microservice.spring.ioc.annotation子包,但是Spring还是扫描了cn.org.microservice.spring.ioc.annotation子包。SpringBoot用的就是这个原理。通过Spring Boot 原理解析—入口SpringApplication一篇我们知道Spring Boot启动类上包含Configuration注解和@ComponentScan,我们运行main方法的时候只需要将主类注册到Spring容器中,后续就会扫描主类包下