首页 > 其他分享 >springboot 注解学习之——@SpringBootApplication

springboot 注解学习之——@SpringBootApplication

时间:2023-11-14 21:33:05浏览次数:38  
标签:springboot spring SpringBootApplication 配置 自动 注解 class configurations

springboot 注解学习之——@SpringBootApplication

springboot 版本3.1.5

@Inherited //不认识的注解,顺便学习,字面意思:继承
@SpringBootConfiguration  //字面意思:SpringBoot配置
@EnableAutoConfiguration  //字面意思:可以自动配置

@Inherited

它是一个元注解(就是用来声明注解类型时需要使用到的注解。也叫标记注解),Inherited作用是,使用此注解声明出来的自定义注解,在使用此自定义注解时,如果注解在类上面时,子类会自动继承此注解,否则的话,子类不会继承此注解。这里一定要记住,使用Inherited声明出来的注解,只有在类上使用时才会有效,对方法,属性等其他无效。

简单来说就是@SpringBootApplication这个注解被@Inherited修饰,那么SpringbootXXXApplication这个类的子类,就会自动继承@SpringBootApplication这个注解。

@SpringBootConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration         //没什么特殊的,它是spring配置注解,也就是可以SpringbootXXXApplication这个类里面配置bean。
@Indexed
public @interface SpringBootConfiguration {
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}

@EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage   //自动配置包
@Import({AutoConfigurationImportSelector.class})  //引入一个类(自动配置引入选择器类)
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

    String[] excludeName() default {};
}

到这儿可以看出springboot的核心功能自动装配和这个注解有很大关系,上面的注解没啥东西。

@AutoConfigurationPackage

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({AutoConfigurationPackages.Registrar.class})  //这里引入了一个类,自动配置包的内部类,注册。所需要的包都是Registrar注册的?
public @interface AutoConfigurationPackage {
    String[] basePackages() default {};

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

看下Registrar

//ImportBeanDefinitionRegistrar to store the base package from the importing configuration.	
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
		// 注册bean的定义,就是自己注册bean,通过注解元数据
		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
			register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
		}
	    // 确认一下?
		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
			return Collections.singleton(new PackageImports(metadata));
		}

	}

看看怎么注册

	/**
	 * Programmatically registers the auto-configuration package names. Subsequent
	 * invocations will add the given package names to those that have already been
	 * registered. You can use this method to manually define the base packages that will
	 * be used for a given {@link BeanDefinitionRegistry}. Generally it's recommended that
	 * you don't call this method directly, but instead rely on the default convention
	 * where the package name is set from your {@code @EnableAutoConfiguration}
	 * configuration class or classes.
	 * @param registry the bean definition registry
	 * @param packageNames the package names to set
	 */
	//看翻译是把给定的包名注册到spring
	public static void register(BeanDefinitionRegistry registry, String... packageNames) {
         // BEAN = AutoConfigurationPackages.class.getName();
         // 已经有了 BEAN DefinitionRegistry 就直接添加到基础包
		if (registry.containsBeanDefinition(BEAN)) {
            //加到基础包不深究了,应该是都加进去,才能扫描
			addBasePackages(registry.getBeanDefinition(BEAN), packageNames);
		}
        //没有的话,注册BEAN 的定义(真是绕口)
		else {
			RootBeanDefinition beanDefinition = new RootBeanDefinition(BasePackages.class);
			beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
			addBasePackages(beanDefinition, packageNames);
			registry.registerBeanDefinition(BEAN, beanDefinition);
		}
	}

@AutoConfigurationPackage 简单来说,就是用AutoConfigurationPackages类的Registrar这个类,把需要的包注册进基础包,spring就能扫描到

AutoConfigurationImportSelector.class

看字面意思,是选择需要的对象引入。里面很多方法。

有个核心的方法

//获取自动配置入口,通过注解元数据
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return EMPTY_ENTRY;
   }
   AnnotationAttributes attributes = getAttributes(annotationMetadata);
    //这一步,找到候选配置,进去看看
   List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
   configurations = removeDuplicates(configurations);
   Set<String> exclusions = getExclusions(annotationMetadata, attributes);
   checkExcludedClasses(configurations, exclusions);
   configurations.removeAll(exclusions);
   configurations = getConfigurationClassFilter().filter(configurations);
   fireAutoConfigurationImportEvents(configurations, exclusions);
   return new AutoConfigurationEntry(configurations, exclusions);
}
	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
			.getCandidates();
        //这个断言提示 说明需要的配置 默认是从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports这里读取的
		Assert.notEmpty(configurations,
				"No auto configuration classes found in "
						+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

可以看到org.springframework.boot.autoconfigure.AutoConfiguration.imports这个文件里面很多spring内置好的自动配置类。上面的Selector就是通过这个文件去选择配置类。

这些配置类负责注册自己的bean,到spring当中。当然并不是所有的都会成功注入到spring。每个配置类里面还有判断,需要导入starter。

结构图

总结

springboot的自动装配也就那么回事,只不过把我们之前要自己写的配置,全部写好放着了,需要用的时候,直接拿来。

springboot所有自动配置都是在启动的时候扫描并加载:org.springframework.boot.autoconfigure.AutoConfiguration.imports所有的自动配置类都在这里面,但不一定生效,要判断是否成立,只要导入对应的starter,就有对应的启动器,有了启动器,我们自动装配就会生效。

  • spingboot在启动的时候,从配置文件org.springframework.boot.autoconfigure.AutoConfiguration.imports获取指定的配置类。
  • 将这些自动配置类导入容器,自动配置就会生效,帮我们进行自动配置!
  • 以前我们需要自己配置的东西,现在springboot帮我们做了。
  • 整合javaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure-3.1.5.jar这个包下。
  • 它会会把所有需要导入的组件,一类名的方式返回,这些组件会被添加到容器。
  • 容器中也会有很多的XXXAutoConfiguration的Bean,就是这些类注册了这个场景所需要的组件。@Configguration
  • 有了自动装配,免去了我们手动编配置文件的工作

标签:springboot,spring,SpringBootApplication,配置,自动,注解,class,configurations
From: https://www.cnblogs.com/microstar/p/17832638.html

相关文章

  • 214-springboot定时任务@Scheduled
    @Scheduled(fixedDelay=5000)@Scheduled(fixedDelay=5000),是启动后,马上开始第一次执行任务的么?应用启动时,任务会被立即执行。执行完成后,会等待5秒(因为fixedDelay设置为5000毫秒),然后再次执行任务。以后每次执行完任务,都会等待5秒后再次执行。类的注解:@Configuration@Ena......
  • 在linux上部署SpringBoot项目
    部署项目到linux软件安装项目部署1.软件安装1.1软件安装方式在Linux系统中,安装软件的方式主要有四种,这四种安装方式的特点如下:安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布,只要解压,修改配置即可rpm安装软件已经按照redhat的包管理......
  • springboot常用注解
    1、@SpringBootApplication这是SpringBoot最最最核心的注解,用在SpringBoot主类上,标识这是一个SpringBoot应用,用来开启SpringBoot的各项能力。其实这个注解就是 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 这三个注解的组合,也可以用这三......
  • Springboot3核心特性
    一、简介1.前置知识Java17Spring、SpringMVC、MyBatisMaven、IDEA2.环境要求环境&工具版本(orlater)SpringBoot3.0.5+IDEA2021.2.1+Java17+Maven3.5+Tomcat10.0+Servlet5.0+GraalVMCommunity22.3+......
  • 【springboot项目运行报错】亲测有效 Parameter 0 of constructor in xxx.xxx.Control
    Parameter0ofconstructorinme.zhengjie.modules.system.rest.DictDetailControllerrequiredabeanoftype'me.zhengjie.modules.system.service.DictDetailService'thatcouldnotbefound.1.点击界面左侧的maven管理,再点击root下的生命周期,点击clean(也可以直接控制台......
  • springboot dto,entity中过滤字符串传入内容的空格
    @Excel(name="商品编号")privateStringproductCode;publicStringgetProductCode(){//过滤空格;returnproductCode.trim();}......
  • springboot+springsecurity+layui+cherryMd博客系统
    演示地址:http://175.24.198.63:9090/front/indexPS:演示环境的服务器配置很低,带宽很小,若打开速度较慢,稍微等等哦~现在动不动就是前后端分离,其实访问量不大博客这种项目,没有必要为了分离而分离。SpringBoot+LayUI:快速开发:LayUI是一个简单的UI框架,它提供了易于使用的组......
  • springboot 3 知识点总结
    一、springboot相关1.类中添加@RestController、方法中添加@GetMapping注解可实现web的路由和数据返回;这两个注解不是springboot的是注解,是springMVC的注解2.在controller的方法中的参数中添加@RequestPara(value="name",defaultValue="word")可以实现浏览器get参数的接收......
  • SpringBoot系列之集成Redission入门与实践教程
    Redisson是一款基于java开发的开源项目,提供了很多企业级实践,比如分布式锁、消息队列、异步执行等功能。本文基于Springboot2版本集成redisson-spring-boot-starter实现redisson的基本应用软件环境:JDK1.8SpringBoot2.2.1Maven3.2+Mysql8.0.26redisson-spring-boot-starter3.15.......
  • 使用JWT、拦截器与ThreadLocal实现在任意位置获取Token中的信息,并结合自定义注解实现
    1.简介1.1JWTJWT,即JSONWebToken,是一种用于在网络上传递声明的开放标准(RFC7519)。JWT可以在用户和服务器之间传递安全可靠的信息,通常用于身份验证和信息交换。声明(Claims):JWT包含一组称为声明的信息,声明描述了一些数据。有三种类型的声明:注册声明(RegisteredClaims):这是......