Springboot--Springboot相关注解

1、@SpringBootApplication  

   写在应用主启动类上

@SpringBootApplication
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

点进去这个注解可以看到这个注解上面有以下主要注解

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)

        1.1、@EnableAutoConfiguration

        启用 SpringBoot 的自动配置机制,在springboot中有很多Enable开头的就是启用某个功能。在@EnableAutoConfiguration注解类的上面又有以下注解

@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

                1.1.1、@AutoConfigurationPackage

        这个注解的作用就是将 添加该注解的类所在的package 作为 自动配置package进行管理。我们知道组合注解就相当于各个单注解都添加到一个作用目标的作用(有关注解可以看这个:Java注解:元注解、普通注解、组合注解_jcpp9527的博客-CSDN博客)因为相当于SpringbootApplication这个注解间接组合了AutoConfigurationPackage那么搭配这个注解的作用也就是说当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package。可以使用下面的方式检测当前的自动配置的包。

@Autowired
public BeanFactory beanFactory;

List<String> packages = AutoConfigurationPackages.get(beanFactory);
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})

 这个注解又包含这些注解,也就说AutoConfigurationPackage这个注解主要是通过@Import导入了一个类,这个@Import注解大家应该都熟悉,(它是spring底层注解,作用就是将注解内参数表明的类加入IOC容器。不要以为像@Controller、@Service、@Component这些就很好的可以解决,其实对于一些jar包中没有使用@Component注解的类,我们总不能打开jar包给人家加上吧,这时候这个@Import就起到作用了),回到源码中,导入的这个类Register.class也就是AutoConfigurationPackages.Registrar.class,这个类中会完成我们上面所说的AutoConfigurationPackage注解的功能,将主配置类所在的包下面所有的组件都扫描到Spring容器中。

                1.1.2、@Import({AutoConfigurationImportSelector.class})

        添加AutoConfigurationImportSelector.class到IOC容器,有关这个类请看后面。

        1.2、@SpringBootConfiguration

        这个注解里面就是一个@Configuration,也就是说它的功能和@Configuration是一样的也就是标注这个注解的类就是一个配置类,只不过这个派生注解给人见名知意的感觉,被标注者它就是Springboot的配置类。

        1.3、@ComponentScan

@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}

这个设置包扫描的。在其注解定义中有如下字段,

public @interface ComponentScan {

	@AliasFor("basePackages")
	String[] value() default {};

	@AliasFor("value")
	String[] basePackages() default {};

	Class<?>[] basePackageClasses() default {};

	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;

	boolean useDefaultFilters() default true;

	Filter[] includeFilters() default {};

	Filter[] excludeFilters() default {};

	boolean lazyInit() default false;


	@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {
		FilterType type() default FilterType.ANNOTATION;

		@AliasFor("classes")
		Class<?>[] value() default {};

		@AliasFor("value")
		Class<?>[] classes() default {};

		String[] pattern() default {};
	}

}

下面给出解释:

basePackages与value:  用于指定包的路径,进行扫描

basePackageClasses: 用于指定某个类的包的路径进行扫描

nameGenerator: bean的名称的生成器

useDefaultFilters: 是否开启对@Component,@Repository,@Service,@Controller的类进行检测

includeFilters: 包含的过滤条件

excludeFilters: 排除的过滤条件

        有关过滤(@Filter注解),它又是本注解的内部注解,它有四个字段

		FilterType type() default FilterType.ANNOTATION; //指定过滤类型,后边会说这个过滤类型有啥
		@AliasFor("classes")
		Class<?>[] value() default {};  //如果过滤类型为自定义时,给出的过滤器类,给定类型时、以及注解类型时用来设置需要过滤的类以及根据什么样的注解过滤

		@AliasFor("value")
		Class<?>[] classes() default {};

		String[] pattern() default {};  //AspectJ类型时过滤表达式,正则表达式规则时的正则表达式式

        FilterType是个枚举主要有以下过滤类型

public enum FilterType {
	ANNOTATION,   //根据注解,即标注指定注解的通过过滤
	ASSIGNABLE_TYPE,  //根据自定过滤哪些类
	ASPECTJ, //根据ASPECTJ表达式过滤
	REGEX,   //正则表达式过滤
	CUSTOM  //自定义过滤
}

         更过有关自定义过滤规则请看 https://blog.csdn.net/nrsc272420199/article/details/88385574

@Component默认情况下,任何参数都不设置的情况下,此时,会将@ComponentScan修饰的类所在的包作为扫描包。

另外在springboot的启动类上,也就是被@SpringbootApplication所标注的类上,如果你再只加入一个@ComponentScan(什么参数都不加的情况),是会报冗余错误的,因为@SpringbootApplication已经包含@ComponentScan,只有参数与默认的也就是主启动类所在不一样的包下才可以。但是这样就会覆盖@SpringbootApplication组合的@ComponentScan,所以你需要再将@SpringbootApplication的里面的@ComponentScan所扫描包再使用@ComponentScan重新写一次(惊讶的发现此时搭配另外的@ComponentScan就不会再出错了)

更多请看​​​​​​Spring Boot踩坑记录(@SpringBootApplication与@ComponentScan存在冲突) - 司徒无涯的个人空间 - OSCHINA - 中文开源技术交流社区

那么让我们最后回到SpringbootApplication中的@Component,可以看出,其指定了两条过滤规则,并指定了过滤规则类。

2、@EnableAutoConfiguration-@Import({AutoConfigurationImportSelector.class})

这个本应该在在1.1.2中讲,但是单独拿开,足以说明其很重要。

也就是说在@EnableAutoConfiguration里面组合了一个@Import({AutoConfigurationImportSelector.class}),作用显而易见,将AutoConfigurationImportSelector.class这个类加入到springIOC容器,那么这个类是什么作用呢?接着看,在SpringBoot中存在大量的XXXAutoConfiguration,这些AutoConfiguration类就是帮我们进行自动配置的,他们会将指定场景使用到的所有组件都注册到容器中并且配置好。,这些类的全类名可以在

 也就是在类路径下META-INF/spring.factories文件中,在这个文件有一部分

 这个键对应的值,也就是等号后边的东西,会在AutoConfigurationImportSelector这个类的getCandidateConfigurations这个方法中,具体的会调用到SpringFactoriesLoader这个类的loadSpringFactories里面将字符串读入,分割等一系列操作,最后返回一个List集合,springboot会将集合中的全类名都加载到IOC容器中。

但是呢请注意,META-INF/spring.factories可不止一个,在其他的包下也可以可以有

 这里面标线的方法和操作,就是将所有的spring.factories文件读入,并将其中的key和value封装成LinkedMultiValueMap,这个结构的一个key可以对应多个value,可以认为是这样的结构:Map<String, List<String>>,方法返回后会在getOrDefault(factoryTypeName, Collections.emptyList());中返回key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的list集合,这个集合中就是哪些自动配置的全限定类名。这其实是加载bean的一种方式,和import一样的理解就行。

Spring中的spring.factories文件(Spring如何加载第三方Bean)_程序猿新手_曹先生的博客-CSDN博客​​​​​​z引言在springBoot中,它自动扫描包的时候,只会扫描自己模块下的类。问题如果我们不想被Spring容器管理的Bean的路径下不再SpringBoot的包扫描路径下,怎么办呢?如何加载别的第三方Bean呢?解决首先我们创建一个工程,另外创建一个与启动类不在一个级别的目录。第一种方法就是使用在启动类上加上@Import注解。@Import(value = {Test.class})第二种方法就是创建spring.factories文件现在我们将其改造一下,采用spring.fachttps://blog.csdn.net/qq_41691210/article/details/110676863

 
 
 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值