自动装配案例首先我们通过一个案例来看一下自动装配的效果,创建一个SpringBoot工程,在pom文件中添加如下依赖。<依赖>org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-data-redis其中web依赖是指我们是一个web项目,redis依赖是我们这边要验证的功能依赖.然后在application.properties配置文件中添加redis的相关配置如下spring.redis.host=localhostspring.redis.port=6379spring.redis.password=123456然后写一个Controller和Service类,相关代码如下.包com.example.demo.controller;导入com.example.demo.service.HelloService;导入org.springframework.beans.factory.annotation.Autowired;导入org.springframework.web.bind.annotation.GetMapping;导入org.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassHelloController{@AutowiredprivateHelloServicehelloService;@GetMapping(value="/hello")publicStringhello(@RequestParam("name")Stringname){returnhelloService.sayHello(name);}}service代码如下packagecom.example.demo.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.stereotype.Service;@ServicepublicclassHelloService{@AutowiredRedisTemplateredisTemplate;publicStringsayHello(Stringname){Stringresult=doSomething(name);关于disTemplate.opsForValue().set("名称",结果);结果=redisTemplate.opsForValue().get("名称");返回“你好:”+结果;}privateStringdoSomething(Stringname){returnname+"欢迎关注";}}启动项目,然后我们访问http://127.0.0.1:8080/hello?n就可以看到访问正常了...接下来我们可以通过Redis客户端观察数据是否正确写入Redis,效果和我们想象的一致。自动组装分析看到这里,很多朋友会说,我天天用这种写法,用起来真的爽。虽然用起来很爽,但是大家有没有想过一个问题,就是我们在我们的HelloService中通过@Autowired注入了一个RedisTemplate类,但是我们的代码中并没有写这个类,也没有使用类似@的东西RestController、@Service等注解将RedisTemplate注入到SpringIoC容器中,那么为什么我们可以通过@Autowired注解从IoC容器中获取到RedisTemplate类呢?这里就是常说的自动装配的作用。首先我们看一下项目的启动类;包com.example.demo;导入org.springframework.boot.SpringApplication;导入org.springframework.boot.autoconfigure.EnableAutoConfiguration;导入org.springframework.boot.autoconfigure.SpringBootApplication;导入org。springframework.context.annotation.ComponentScan;@SpringBootApplication@ComponentScan(value="com.example.demo.*")publicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}}启动类上有一个@SpringBootApplication注解,我们可以点击查看如下内容:={@Filter(type=FilterType.CUSTOM,classes={TypeExcludeFilter.class}),@Filter(type=FilterType.CUSTOM,classes={AutoConfigurationExcludeFilter.class})})public@interfaceSpringBootApplication{//此处省略}在注解中,有一个@EnableAutoConfiguration注解,正是因为有了这样的注解,我们才能实现自动装配的功能。继续往下看。@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import({AutoConfigurationImportSelector.class})public@interfaceEnableAutoConfiguration{StringENABLED_OVERRIDE_PROPERTY="spring.boot.enableautoconfiguration";类>[]排除()默认{};String[]excludeName()default{};}可以看到在@EnableAutoConfiguration注解中有一个@Import({AutoConfigurationImportSelector.class}),它引入了一个AutoConfigurationImportSelector类,间接实现了ImportSelector接口,并且一个String[]selectImports(AnnotationMetadataimportingClassMetadata);方法实现。该方法的返回值是一个字符串数组,对应一系列主要注入SpringIoC容器的类名。当在@Import中导入一个ImportSelector实现类时,该实现类中返回的Class名会被加载到IoC容器中。一旦加载到IoC容器中,我们就可以稍后使用@Autowired。接下来我们看selectImports方法中的实现,它引用了getCandidateConfigurations方法。我们可以看到ImportCandidates.load方法是通过Stringlocation=String.format("META-INF/spring/%s.imports",annotation.getName());来加载的对应路径中的org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,里面包含了很多自动组装的配置类。protectedListgetCandidateConfigurations(AnnotationMetadatametadata,AnnotationAttributesattributes){List配置=newArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(),this.getBeanClassLoader()));ImportCandidates.load(AutoConfiguration.getBeanClassLoader()).forEach(configurations::add);Assert.notEmpty(configurations,"NoautoconfigurationclassesfoundinMETA-INF/spring.factoriesnorinMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。如果您使用自定义包装,请确保该文件是正确的。”);返回配置;我们可以看到在这个文件中有一个RedisAutoConfiguration配置类,里面有我们需要的RedisTemplate类,同时也可以看到类上有@ConditionalOnClass({RedisOperations.class})注解,这意味着它只有在类路径上有RedisOperations.class类时才会被实例化。这就是为什么我们只要添加依赖,就可以自动组装的原因。通过org.springframework.boot.autoconfigure.AutoConfiguration.imports文件可以看到官方已经为我们实现了很多配置类。这些功能只需要在pom文件中添加相应的starter依赖,然后做一些简单的配置即可。可以直接使用。本质上,自动装配的原理很简单。本质上需要实现一个配置类,但是这个配置类是官方为我们创建的,并且添加了一些条件类注解,使得对应的实例化只发生在类路径上。仅在某些类存在时触发。这个配置类和我们平时写的JavaConfig形式的配置类没有本质区别。自动组装小结从上面的分析可以看出,很多时候我们之所以使用SpringBoot之所以这么简单,都是基于约定好于配置的思想。框架底层默认了很多复杂的逻辑。实现。虽然用起来很爽,但往往让程序员搞不懂原理。我们要做的不仅仅是会用,还要知道底层逻辑,才能走得更远。通过上面的分析,我们也可以知道,如果我们要实现自己的starter,其实也很简单,只要安装上面的约定,编写自己的配置类和配置文件即可。下一篇文章,阿芬将带大家手写自己的starter,详细实现。