目录
3.1 @SpringBootConfiguration注解
3.2 @EnableAutoConfiguration注解
1.Spring如何加载我们的类的
相信在刚开始学习Spring的时候,我们都学过如何用spring的配置来指定类之间的关系,例如:
<bean id="englishMessageProvider" class="innerspring.com.decoupled.EnglishMessageProvider"/>
<bean id="standardOutMessageService" class="innerspring.com.decoupled.StandardOutMessageService"
p:messageProvider-ref="englishMessageProvider"/>
后面的class就是我们自己实现的业务类,例如:
package innerspring.com.decoupled;
public class EnglishMessageProvider implements IMessageProvider {
public EnglishMessageProvider(){
System.out.println(" --> EnglishMessageProvider: constructor called");
}
@Override
public String getMessage() {
return "Hello World!";
}
}
我们在使用的时候只要这么写就行了:
public class HelloWorldSpringDI {
public static void main(String... args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext
("spring/app-context.xml");
IMessageService mr = ctx.getBean("standardOutMessageService", IMessageService.class);
mr.execute();
}
}
初次接触Spring的时候,通过上面的代码,并且仔细研究ClassPathXmlApplicationContext的代码,可以逐步梳理出Ioc、AOP等的完整过程,虽然复杂,如果花时间多就足以将其完整搞清楚是如何加载的。
不过呢使用XML的方式有一个很大的问题,就是如果我们的类非常多非常复杂,这时候xml的配置就无比庞大,而如果我修改了版本或者实现等等,此时维护xml文件就是个灾难。
为此Spring发展的一个重要途径就是推广使用注解,减少xml等配置的内容。例如上面我们定义的bean:
<bean id="englishMessageProvider" class="innerspring.com.decoupled.EnglishMessageProvider"/>
这里的关键是class里指定的类的路径和类名,而前面的id就是类名的小写,所以我们只要找到类就完全能自己创建出这么一个类来。
那不用配置又该如何找到我们的类呢?方法是用注解+包扫描
凡是用过SpringBoot的同学应该都知道,我们写了一个服务之后,都需要在头部加上这么一个注解,例如@Controller、@Service或者@Component等等,例如:
@Service
@Slf4j
public class TeacherService implements ITeacherService {
}
然后在使用的时候这么写就可以了:
@Autowired
private ITeacherService teacherService;
这种代码在我们的工程里大量出现。那Spring里的注解是一蹴而就的吗?SpringBoot又是如何使用了Spring的注解进行封装,并且还做了哪些工作呢?我们继续讨论。
2.Spring注解驱动发展史与核心注解介绍
2.1 Spring驱动发展简史
Spring在刚刚发布的时候,管理Bean主要使用xml,在1.2.0版本仅仅支持@Transaction等少量几个注解。
到了2006年,Spring2发布,其中的Spring2.5是一个重要的分水岭,此时Spring引入了多个非常重要,至今仍然大量使用的注解:
1.依赖注入注解 @Autowired
2.依赖查找注解 @Qualifier
3.组件声明注解:@Service或者@Component
4.SpringMVC注解:@Controller、@RequestMapping,@ModelAttribute等等。
之后到了Spring3系列,此时引入的一个非常重要的注解是@Configuration注解,用于完成配置相关的类。
为了替换配置,Spring3还增加了一个@Bean注解,这样就可以使用@Configuration和@Bean组合来声明一个Bean了。这个我们后面小节单独介绍如何使用。
Spring3里还引入了很多重要的注解,例如@RequestHeader、@RequestBody,@Validate等等
不过呢,Spring3此时并没有引入扫描包的component-scan的,而是引入了两个更加基础的注解@ImportResource和@Import,前者允许引入xml配置文件,后者允许导入一个或者多个类作为SpringBean,这个@Import是一个非常重要的注解,我们后面研究SpringBoot的原理还会看到这个类。后面小节我们单独研究一下@Import注解。
到了Spring4,引入的是条件注解是@Conditional,并且引入了@ComponentScans。到了Spring4在注解方面基本完备了,例如引入了@GetMapping、@RequestMapping、@RestController等等。
除此之外还有其他的注解,例如事件监听器注解@EventListener、@CrossOrigin、@Lookup等。
到了Spring5里 ,注解已经没有太多变动了,只有一个@Index索引,用以提高性能。
2.2 @Configuration和@Bean注解
为了替换配置,Spring3还增加了一个@Bean注解,这样就可以使用@Configuration和@Bean组合来声明一个Bean了。
我们还是写个案例尝试一下:
先定义一个类:
@Configuration
publ