SpringBoot自动装载详解

自动装配前的了解阶段

如果一上来就说这些注解是这样的,那个注解是干那个功能的,那么就会完全不理解,肯定会懵,所以咱们边实战边了解注解,带着思考看这些问题。

首先在使用SpringBoot之前,我们还没有开始写业务代码,搭建框架可能就需要很多时间,假如SringMVC就需要添加依赖,考虑版本,还需要添加SpringMVC XML的文件等等等都需要配置,然后才能写业务代码,然后最后部署到tomcat步骤相当繁琐,相当麻烦。

但是springboot的出现解决了spring默认添加的依赖版本问题,也不需要写SpringMVC xml的各种文件去配置,也不需要手动部署到tomcat上,只需要关注业务逻辑代码编写,springboot用固定的东西做成一个约定的模版,按照约定去创建去配置,springBoot自动就会做以上的操作,不用我们操心,省下繁重的工作。

Springboot只要引入以下web的包,就可以自动引入很多Spring的包以及其他jar包

在之前Spring需要注入属性对象,需要在applicationContext.xml以<bean>去实现,随着属性越来越多,配置文件会增多,bean会增多,带来维护困难。然后在springboot中出现了注解(@Service,@Componet,@Controller等等)等价于<bean>

去配置化JavaConfig:就是不使用Spring里的XML,完全用注解方式匹配

咱们先示例一下@Configuration注解类的使用,了解一下关于注解的秘密

咱们先创建一个configDemo类,下图加上@Configuration其实就是做了SpringMVC的xml配置的操作。

// 这个@Configuration就是配置类,相当于Spring中的ApplicationContext.xml
@Configuration
public class configDemo {
    @Bean
    public TestService testService() {
        return new TestService();
    }
}
public class TestService {
}

然后进行测试调用就能从容器里获得对应的实例。其实就是通过@Configuration或@Bean注解进行的IOC注入操作。

 public static void main(String[] args) {
       // 这个也等同Configuration,也是可以直接将configDemo直接注入到IOC
       // configDemo类也可不加@Configuration,但是类里一定要注入TestService的Bean实例
       ApplicationContext context = new
               AnnotationConfigApplicationContext(configDemo.class);
       System.out.println(context.getBean(TestService.class));
 }

运行main方法,发现是能在容器里获取对应实例的。

那么我还想在当前configDemo类注册其他类呢,假如我要获取configDemo1下的TestService1的实例,那么我们来看一下

@Configuration
public class configDemo1 {
    @Bean
    public TestService1 testService1() {
        return new TestService1();
    }
}
public class TestService1 {
}

Main方法获取bean试一下,注意此时就是想要查找configDemo类里获取TestService1类

public static void main(String[] args) {
     ApplicationContext context = new
              AnnotationConfigApplicationContext(configDemo.class);
     System.out.println(context.getBean(TestService1.class));
}

报错了,原因是bean里没有注入类

那么怎么解决呢,1是可以这样解决

 public static void main(String[] args) {
        ApplicationContext context = new
                AnnotationConfigApplicationContext(configDemo.class,configDemo1.class);
        System.out.println(context.getBean(TestService1.class));
    }

但是不想要这样实现,其实还有注解那一种方式。加上@Import(),@Import(),就是导入其他配置的注解,那么加上这个注解以后就会把相应的类在容器中注入

在configDemo中加上@Import()

@Configuration
@Import(TestService1.class)
public class configDemo {
    @Bean
    public TestService testService() {
        return new TestService();
    }
}

main方法测试发现这样也是能获取实例的

public static void main(String[] args) {
        ApplicationContext context = new
                AnnotationConfigApplicationContext(configDemo.class);
        System.out.println(context.getBean(TestService1.class));
    }

通过以上的操作我们发现已经完全去除了Spring的配置文件

但是还不够,如果我们需要引入一个redis我们是不是还要写一个redisConfi配置文件,jdbc连接是不是还需要写DataSourceConfig,就类似如下的这个图片。

哎对了就是@EnableXXX,SpringBoot里有很多@EnableXXX的注解,那么这个注解能解决这个问题呢?就是@EnableXXX这个注解,我们也自定义一个注解,看怎么实现,首先我创建一个注解类,叫EnableMyRedis

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(RedisConfig.class)
public @interface EnableMyRedis {
}

我模拟一个想要配置Redis的类加载到容器中

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplete redisTemplete() {
        return new RedisTemplete();
    }
}
public class RedisTemplete {
}

那么假如我要用redis的配置我就可以这样使用了

@Controller
@EnableMyRedis
public class DemoController {
}

那么你就会发现我不需要写RedisConfig的类了,这个RedisConfig类可以放到第三方jar包,我们直接引入jar写上@EnableXXX使用即可。

那假如我又要引入RedisTemplete,还要引入Mybaties的东西呢,我们知道要是使用@Autowired,那么这个对象一定是被注入的,那么是怎么注入的呢,都是在不同的包啊,redis是redis的包,mybatis是mybatis其他路径的包,甚至还有很多包都在用它们,那如何才能Spring扫描到它并加载到IOC里,供我们使用呢?

首先我们加进来一个Mybatis的包

<dependency>
     <groupId>org.mybatis.spring.boot</groupId>
     <artifactId>mybatis-spring-boot-starter</artifactId>
     <version>2.1.1</version>
</dependency>

找到mybatis自动配置的包,看到spring.factories文件,点击进去

EnableAutoConfiguration代表自动配置的key,底下有两个value值是自动配置类这样就知道它的路径了

点击任意配置就能看见里边都是加载到IOC操作,各种bean操作

其实查看springboot的自动配置包也能看见这个spring.factories文件,点击进去会有很多的配置类。

看这不就是需要注入的redis的配置地址么

我们Spring就是通过spring.factories这个文件里配置的地址,扫描加载IOC的操作。扫描的过程是采用SpringFactoriesLoder也就是SPI机制进行扫描的,然后进行装配。

然后接下来看一下SpringBoot怎么装载的呢?

找到springboot的启动类在点击进去

点击自动配置注解

@Import很熟悉把,而且见名知意是要导入自动配置类,再点击AutoConfigurationImportSelector

查看selectImports方法,在下图所示的地方点个断点,启动主main

进入断点,发现这个list很熟悉,其实这个就是我们之前看到的spring.factories文件里的自动配置,在代码里有被获取到,configurations之后的代码就是去重过滤什么的。我们看一下getCandidateConfigurations方法。

很熟悉把用的是SpringFactoriesLoader加载的,而且也能看出是找的spring.factories文件

点击这个方法

这个EnableAutoConfiguration不就是第二个图配置文件里的名称么

总结

@SpringBootApplication等同于下面三个注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

其中@EnableAutoConfiguration是关键(启用自动配置),内部实际上就去加载META-INF/spring.factories文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能!

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值