zoukankan      html  css  js  c++  java
  • SpringBoot高级-自动配置之Enable*注解原理

    前言:SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载。所以,SpringBoot的自动配置,就是依赖于各种Enable开头的注解,而Enable开头的注解,又依赖于@Import注解实现的。

    首先,我们来看SpringBoot引导类上的注解@SpringBootApplication,进一步了解引导类中使用的Enable开头的注解。

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

    进入@SpringBootApplication注解中,可以看到,除了三个元注解(元注解这里不解释了,固定用法,所有的注解都包含这三个注解),主要起作用的其它注解,分别解释。

    一、@Inherited注解:这个注解的作用可以自己看,讲的很详细,也有示例。链接:https://www.jianshu.com/p/7f54e7250be3 ,主要作用是
    ①、类继承关系中@Inherited的作用:类继承关系中,子类会继承父类使用的注解中被@Inherited修饰的注解

    ②、接口继承关系中@Inherited的作用:接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰

    ③、类实现接口关系中@Inherited的作用:类实现接口时不会继承任何接口中定义的注解

    二、@SpringBootConfiguration注解的作用,先进入该注解中,发现该注解就是声明一个配置类,因此,在SpringBoot引导类中,我们也可以定义Bean。

    三、@EnableAutoConfiguration注解,进入该注解中,可以发现,其最终是使用了@Import注解,导入一些配置

    四、@ComponentScan注解作用:组件扫描。扫描范围:当前引导类所在包及其子包。

    综上,@SpringBootApplication注解,依赖的最重要注解就是@EnableAutoConfiguration,及间接依赖的@Import注解。

    下面我们做一个示例:验证SpringBoot工程能否直接获取jar包中定义的Bean

    一、首先,我们新建一个SpringBoot工程springboot-enable,获取user的Bean

    @SpringBootApplication
    public class SpringbootEnableApplication {
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
    
            Object user = context.getBean("user");
            System.out.println(user);
        }
    }
    

    二、再新建一个SpringBoot工程springboot-enable-user,定义User实体类和User配置类
    User实体类

    /**
     * @description:user实体类
     * @date: 2020/10/10 10:29
     * @author: winson
     */
    public class User {
    }
    

    User配置类

    /**
     * @description:User配置类
     * @date: 2020/10/10 10:29
     * @author: winson
     */
    @Configuration
    public class UserConfig {
        @Bean
        public User user() {
            return new User();
        }
    }
    

    三、在springboot-enable工程中,导入springboot-enable-user工程的依赖

    <dependency>
        <groupId>com.winson</groupId>
        <artifactId>springboot-enable-user</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
    

    四、启动程序,测试user是否注入到了IOC容器中。

    结论:SpringBoot工程不能直接获取jar包中定义的Bean

    接着上述结果,说明为什么不能直接获取jar包中定义的Bean,这跟引导类@SpringBootApplication注解上的@ComponentScan注解有关系,上述提到了该注解,其扫描范围为引导类所在的包及其子包,而上述测试用的User配置类并不在这个范围内,所以无法获取到。

    引导类所在的包为:com.winson.springbootenable
    User配置类所在的包为:com.winson.config

    下面就上述问题,给出答案,实现SpringBoot工程可以获取jar包中定义的Bean

    方法一、使用@ComponentScan注解,将User配置类所在包,加入扫描范围
    修改引导类,加入@ComponentScan注解,将User配置类所在包,加入扫描范围

    @SpringBootApplication
    @ComponentScan("com.winson.config")
    public class SpringbootEnableApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
    
            Object user = context.getBean("user");
            System.out.println(user);
        }
    
    }
    

    测试结果:可以发现这时可以获取user的Bean。

    方法二、使用@Import注解,将User配置类导入到引导类中

    @SpringBootApplication
    @Import(UserConfig.class)
    public class SpringbootEnableApplication {
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
    
            Object user = context.getBean("user");
            System.out.println(user);
        }
    }
    

    测试结果:也可以获取user的Bean。

    方法三、对@Import注解进行封装

    一、新建一个注解类@EnableUser,使用@Import导入User配置类UserConfig

    /**
     * @description:封装@Import注解
     * @date: 2020/10/10 11:20
     * @author: winson
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(UserConfig.class)
    public @interface EnableUser {
    }
    

    二、在引导类中,使用@EnableUser注解

    @SpringBootApplication
    @EnableUser
    public class SpringbootEnableApplication {
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
    
            Object user = context.getBean("user");
            System.out.println(user);
        }
    }
    

    三、启动程序,测试结果:也可以获取user的Bean。

    小结:SpringBoot自动配置依赖于各种@Enable开头的注解,@Enable开头的注解,底层还是通过@Import注解实现的,所以自动配置的最核心就是使用了@Import注解

  • 相关阅读:
    Laravel自动备份到阿里云OSS
    《Modern PHP》读书笔记
    支持IE6、IE7、IE8等低端浏览器的简化版vue
    利用SSH 反向代理 ,实现跨局域网连接家里的linux 主机 (树莓派)
    tensorflow-gpu安装脚本
    c++后台开发面试常见知识点总结(六)算法手写
    c++后台开发面试常见知识点总结(五)场景设计
    c++后台开发面试常见知识点总结(四)数据库
    c++后台开发面试常见知识点总结(三)操作系统
    c++后台开发面试常见知识点总结(二)网络编程
  • 原文地址:https://www.cnblogs.com/elnimo/p/13789322.html
Copyright © 2011-2022 走看看