【SpringBoot】自动配置&&自动加载controller的原理

SpringBoot自动配置&&自动加载controller的原理.md

好久没有更新自己的博客了,自己最近的正好有点空闲的时间进行,自己在写着写着,突然想起来,

为什么我们点击application就能自动加载@Controller呢?(好家伙,我顿时鱼鳃,哈哈)

1.首先我们来到启动现场===>启动类

@SpringBootApplication
public class TestApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(ActAfterApplication.class);
    }

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

我们会看到在TestApplication启动类上会有一个注解:@SpringBootApplication

这个注解,就是我们今天的文章的核心,核心**,核心**!!!=====>你可能会说,我问怎么加载@Controllerd的,你给我看这些干啥子?别急啊!大白(●—●),我们向下看

2.@SpringBootApplication剖析

首先我们看点击这个注解进去的当中的三个关键注解

  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  3. @ComponentScan ====> 这个注解就是我们为什么Spring会加载@Controller组件关键所在
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration           //重点======================
@EnableAutoConfiguration			//重点===================
@ComponentScan(excludeFilters = {   //重点=======================
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

3.@SpringBootConfiguration:

这个注解作用标明此类为配置类,点进去发现就是@Configuration,在加载时加载到Spring IOC

你就把他想成是一个让他拥有配置的角色的作用就行啦===> 给他套个龙袍,当太子

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration    //就是这个注解最关键=====================================
public @interface SpringBootConfiguration {

}

4.@EnableAutoConfiguration

**作用:**这个注解可以说是Springboot的灵魂,自动配置,也就是将我们配置文件配置的配置类都加载进来,

它会扫描jar包下面的META-INF/spring.factories文件,将所有符合条件的自动配置类加载到IOC容器中====>是自动配置的核心

为什么?我们点进源码去看看呗,如下的源码,我们会看其中有两个核心的注解 (就是自动配置的关键,这两个注解说明,可以不看,忽略直接看下一个核心注解)

1.@AutoConfigurationPackage

2.@Import(AutoConfigurationImportSelector.class)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

4.1 @AutoConfigurationPackage

点击源码,我们会看到其中的一个: @Import(AutoConfigurationPackages.Registrar.class)

**作用:**借助@Import注解导入符合自动配置类的集合,目的为了加载到IOC容器中

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

AutoConfigurationPackages.Registrar.class的源码,这个可以直接忽略,感兴趣的可以看看

	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata,
				BeanDefinitionRegistry registry) {
			register(registry, new PackageImport(metadata).getPackageName());  //获取包名
		}

		@Override
		public Set<Object> determineImports(AnnotationMetadata metadata) {
			return Collections.singleton(new PackageImport(metadata));
		}

	}

4.2@Import(AutoConfigurationImportSelector.class)

这个类就更重要了,问什么这样说?让我们结合下面的源码一起解读(为了阅读的便利性,只保留所需源码的核心块)

  1. 根据引入的AutoConfigurationImportSelector中的selectImports方法,
  2. 读取所有依赖jar包下面也就是META-INF/spring.factories 下面的文件(怎么借加载此目录下面的呢?===>请看getCandidateConfigurations讲解)
  3. 并且根据加载的条件加载项目所需要的类

通过这三个步骤,也就完成SpringBoot的自动加载 ===> 从而@AutoConfigurationPackage执行结束

public class AutoConfigurationImportSelector
		implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,
		BeanFactoryAware, EnvironmentAware, Ordered {

	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		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 = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return StringUtils.toStringArray(configurations);
	}

getCandidateConfigurations:

为了便于确认,我将AutoConfigurationImportSelector类下面此方法单独拎出来

z这个方法会读取所有的’META-INF/spring.factories’的依赖jar包,

获取spring.factories全名称,====.>其实下面的注解也写了 >点击loadFactoryNames方法,> 加载META-INF/spring.factories

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		Assert.notEmpty(configurations,
				"No auto configuration classes found in META-INF/spring.factories. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

5.@ComponentScan

前面的两个注解说完了,我们终于来到此注解,也是解开我心里疑惑的注解了

就特么我解释吗?===> 就是将我们注册@Controller,@Service,等注解自动扫描加到IOC容器中

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

6.META-INF/spring.factories

这个到底是什么鬼东西???说了半天,我们去看看,其实写这篇博客,按自己也很好奇,哈哈哈

我们走,一起去看看

https://blog.csdn.net/weixin_40017062/article/details/128710518

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot 是基于 Spring 框架开发的快速开发框架。其中 `@Controller` 注解是使用 Spring 框架开发 web 应用的重要组成部分之一。它主要功能是定义控制器,处理 http 请求和响应。下面是 `@Controller` 注解的原理: 1. `@Controller` 注解的作用 `@Controller` 是 Spring 框架的一个注解,用于标识一个类是控制器组件。它的作用是将一个普通的 Java 类标记为 Spring MVC 的控制器组件,告诉 Spring 框架它应该被作为一个控制器来处理请求。 2. Spring MVC 控制器原理 Spring MVC 框架的核心是前端控制器 DispatcherServlet。当请求进入 DispatcherServlet 后,它会根据请求的 URL 去寻找匹配的控制器映射,然后再将请求转发到对应控制器的处理方法。控制器接收到请求后进行处理,然后返回 ModelAndView 对象,将数据和视图返回给 DispatcherServlet。 3. `@Controller` 注解的实现 `@Controller` 注解的实现是基于 Spring IoC 容器。在 Spring IoC 容器启动后,用 `@Controller` 注解注解的类会被自动扫描并注册到 Spring 容器中。然后在 DispatcherServlet 中,通过调用 Spring 容器中的 Bean 执行对应的控制器操作。 4. `@Controller` 注解与其他注解的区别 `@Controller` 注解是 SpringMVC 中最为重要的注解之一。相比其他注解,如 `@RestController`、`@RequestMapping` 等,`@Controller` 更为普遍。它不仅可以用在基于 SpringBoot 的项目中,也可以应用在基于 Spring 框架的其他 Web 项目中。 5. 总结 总之,`@Controller` 注解是 SpringMVC 框架中定义控制器组件的关键注解。它的使用需要基于 Spring IoC 容器的构建和调用,同时与 DispatcherServlet 紧密关联,共同构建了一个完整的 SpringMVC 框架来处理请求和响应。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值