1.背景
随着Spring Boot
的盛行,注解配置式开发受到了大家的青睐,从此告别了基于Spring
开发的繁琐XML
配置。这里先来提纲挈领的了解一下Spring
内部对于配置注解的定义,如@Component、@Configuration、@Bean、@Import
等注解,从功能上来讲,这些注解所负责的功能的确不相同,但是从本质上来讲,Spring
内部都将其作为配置注解进行处理。
对于一个成熟的框架来讲,简单及多样化的配置是至关重要的,那么Spring
也是如此,从Spring
的配置发展过程来看,整体的配置方式从最初比较“原始”的阶段到现在非常“智能”的阶段,这期间Spring
做出的努力是非常巨大的,从XML到自动装配,从Spring到Spring Boot,从@Component到@Configuration以及@Conditional,Spring发展到今日,在越来越好用的同时,也为我们隐藏了诸多的细节,那么今天让我们一起探秘@Component与@Configuration。
我们平时在Spring的开发工作中,基本都会使用配置注解,尤其以@Componen
t及@Configuration
为主,当然在Spring中还可以使用其他的注解来标注一个类为配置类,这是广义上的配置类概念,但是这里我们只讨论@Component和@Configuration,因为与我们的开发工作关联比较紧密,那么接下来我们先讨论下一个问题,就是 @Component与@Configuration有什么区别?
项目推荐:基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装,解决业务开发时常见的非功能性需求,防止重复造轮子,方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化,做到可插拔。严格控制包依赖和统一版本管理,做到最少化依赖。注重代码规范和注释,非常适合个人学习和企业使用
2.@Component与@Configuration使用
2.1注解定义
在讨论两者区别之前,先来看看两个注解的定义:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
String value() default "";
}
复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class)
String value() default "";
boolean proxyBeanMethods() default true;
}
复制代码
从定义来看, @Configuration 注解本质上还是 @Component,因此 @ComponentScan 能扫描到@Configuration 注解的类。
2.2注解使用
接下来看看两者在我们日常开发中的使用:以这两种注解来标注一个类为配置类
@Configuration
public class AppConfig {
}
@Component
public class AppConfig {
}
复制代码
上面的程序,Spring会将其认为配置类来做处理,但是这里有一个概念需要明确一下,就是在Spring中,对于配置类来讲,其实是有分类的,大体可以分为两类,一类称为LITE模式,另一类称为FULL模式,那么对应上面的注解,@Component就是LITE类型,@Configuration就是FULL类型,如何理解这两种配置类型呢?我们先来看这个程序。
当我们使用@Component
实现配置类时:
@Component
public class AppConfig {
@Bean
public Foo foo() {
System.out.println("foo() invoked...");
Foo foo = new Foo();
System.out.println("foo() 方法的 foo hashcode: