16-SpringBoot自动配置-Enable注解原理

2022-03-23 16:11:45 浏览数 (1)

16-SpringBoot自动配置-Enable注解原理

Enable注解原理

@Enable* 注解

SpringBoot提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用 @Import 注解导入一些配置类,实现 Bean 的动态加载。

思考

SpringBoot工程是否可以直接获取在其他工程定义的 bean 呢?

下面我们创建两个工程来演示一下:

  • 一个工程演示如何获取其他工程定义的bean
  • 一个工程编写 bean

案例

1.创建 springboot-enable 工程:用来获取其他工程的 bean

2.创建 springboot-enable-other 工程:用来定义 bean

3.【springboot-enable-other】定义 bean

编写 User 类 以及 返回 User bean 对象的配置类

User:

代码语言:javascript复制
package com.lijw.springbootenableother.domain;

public class User {
}

UserConfig:

代码语言:javascript复制
package com.lijw.springbootenableother.config;

import com.lijw.springbootenableother.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfig {

    @Bean
    public User user(){
        return new User();
    }
}

4.【springboot-enable】引入 【 springboot-enable-other】的工程依赖

代码语言:javascript复制
<!--  引入 springboot-enable-other  -->
<dependency>
    <groupId>com.lijw</groupId>
    <artifactId>springboot-enable-other</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

5.【springboot-enable】获取 【 springboot-enable-other】工程的 User类 bean

代码如下:

代码语言:javascript复制
package com.lijw.springbootenable;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SpringbootEnableApplication {

    public static void main(String[] args) {
        // 获取IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
        // 其他工程
        Object user = context.getBean("user");
        System.out.println(user);
    }

}

从结果来看获取不到 user 的 bean 对象,那么为什么会获取不到呢?

让我们进入一下@SpringBootApplication的注解,如下:

SpringBoot的应用注解默认只会扫描 应用引导类下的包:

如果希望扫描其他工程的 bean,那么可以增加扫描包的范围。

6.【springboot-enable】增加扫描其他工程的包

代码语言:javascript复制
@SpringBootApplication
@ComponentScan("com.lijw.springbootenableother.config")
public class SpringbootEnableApplication {

虽然按照上面的方法,我们已经可以扫描其他工程的类了,但是如果类特别多,这种写法是很不方便的。

我们可以修改一下,采用 @Import 配置类的方式

7.【springboot-enable】使用 @Import 直接导入其他工程的配置类,获取 bean

代码语言:javascript复制
@Import(UserConfig.class)

这样我们也可以获取到配置类中的 bean,虽然比之前扫描包要好,但是如果每次需要这样导入配置类,还是很不方便的。

有没有办法让第三方工程自己定义好注解,我使用的时候直接添加个注解就可以了呢?

这时候我们可以写一个 @Enable* 注解。

8.【springboot-enable-other】定义 @EnableUser 注解类

代码语言:javascript复制
package com.lijw.springbootenableother.config;


import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

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

我们在 @EnableUser 中添加 @Import 配置类的内容,这样就不用让引入工程去写了。

9.【springboot-enable】使用 @EnableUser 导入其他工程的配置类,获取 bean

小结

SpringBoot应用默认扫描不到其他工程的 bean

原因:@ComponentScan 扫描范围:当前引导类所在包及其子包

三种解决方案:

1.使用@ComponentScan扫描第三方工程的包

2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器

3.可以对Import注解进行封装。

重点:Enable注解底层原理是使用@Import注解实现Bean的动态加载

0 人点赞