zoukankan      html  css  js  c++  java
  • spring boot 学习二

    spring boot

    spring boot自动配置实现原理


    1、SpringBoot自动配置-自动加载bean对象到ioc容器

       Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean

      Conditon是条件的意思,属于spring的一个接口,抽象方法为matches,返回值为boolean,两个参数分别为

         ConditionContext:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等

        AnnotatedTypeMetadata:元数据对象,用于获取注解属性  

      Conditon接口

    1 @FunctionalInterface
    2 public interface Condition {
    3     boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
    4 }

       Conditional注解

    1 @Target({ElementType.TYPE, ElementType.METHOD})
    2 @Retention(RetentionPolicy.RUNTIME)
    3 @Documented
    4 public @interface Conditional {
    5     Class<? extends Condition>[] value();
    6 }

      ConditionalOnClass注解

    1 @Target({ElementType.TYPE, ElementType.METHOD})
    2 @Retention(RetentionPolicy.RUNTIME)
    3 @Documented
    4 @Conditional({OnClassCondition.class})
    5 public @interface ConditionalOnClass {
    6     Class<?>[] value() default {};
    7 
    8     String[] name() default {};
    9 }

    通过在配置类上加ConditionalOnClass(“com.alibaba.fastjson.JSON”)就能实现满足导入Json包才能获取类这样的操作,即自动加载bean对象

    springboot 提供的常用条件注解

    • ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
    • ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
    • ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean

    2、SpringBoot自动配置-切换内置web服务器tt

      SpringBoot内置了很多的web容器,有tomcat、jetty、Undertow、netty(nio)等,SpringBoot默认使用的是tomcat服务器,所以在使用其他的web服务器时,需要将默认的给关闭掉,方法是修改pom文件,方式如下

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <!--排除tomcat依赖-->
                <exclusions>
                    <exclusion>
                        <artifactId>spring-boot-starter-tomcat</artifactId>
                        <groupId>org.springframework.boot</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <!--引入jetty的依赖-->
            <dependency>
                <artifactId>spring-boot-starter-jetty</artifactId>
                <groupId>org.springframework.boot</groupId>
            </dependency>

    3、SpringBoot自动配置-Enable注解原理

      SpringBoot不能直接获取在其他工程中定义的Bean(我们定义的bean),spring管理的那些bean是可以的,那如何加载外部工程的bean呢?有以下3中方式

     1 /**
     2  * @ComponentScan 扫描范围:当前引导类所在包及其子包
     3  *
     4  * com.itheima.springbootenable
     5  * com.itheima.config
     6  * //1.使用@ComponentScan扫描com.itheima.config包
     7  * //2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
     8  * //3.可以对Import注解进行封装。
     9  */
    10 
    11 //@ComponentScan("com.itheima.config")
    12 //@Import(UserConfig.class)
    13 @EnableUser
    14 @SpringBootApplication//组合注解,其中有个Configration注解为配置类
    15 public class SpringbootEnableApplication {
    16 
    17     public static void main(String[] args) {
    18         ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
    19 
    20      //获取Bean
    21         Object user = context.getBean("user");
    22         System.out.println(user);
    23 
    24     }
    25 
    26 }
    1. 使用@ComponentScan扫描外部类的配置类的包路径
    2. 使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
    3. Import注解进行封装,在外部工程中封装一个注解,在本工程引导类上加上该注解就可以进行使用该bean
      • 1 封装的Import注解
        2 @Target(ElementType.TYPE)
        3 @Retention(RetentionPolicy.RUNTIME)
        4 @Documented
        5 @Import(UserConfig.class)
        6 public @interface EnableUser {}
    @Enable*这个注解的底层还是@import注解,所以使用@Import导入的类会被Spring加载到IOC容器中。
    而@Import提供4中用法:
    1. 导入Bean 直接@Import(“user.class”)
    2. 导入配置类 直接导入其他工程中的配置类
    3. 导入 ImportSelector 实现类。一般用于加载配置文件中的类@Import(MyImportSelector.class)
      • 1 public class MyImportSelector implements ImportSelector {
        2       @Override
        3       public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        4           return new String[]{"com.itheima.domain.User", "com.itheima.domain.Role"};
        5       }
        6   }

        其他工程定义一个类实现ImportSelector这个借口,重写selectImport方法,将需要的类作为返回值返回

    4. 导入 ImportBeanDefinitionRegistrar 实现类 @Import({MyImportBeanDefinitionRegistrar.class})
      • 1 public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
        2     @Override
        3     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        4         AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
        5         registry.registerBeanDefinition("user", beanDefinition);
        6     }
        7 }
    那么springboot是如何加载管理的那些类呢?怎么样去判断那些类是需要被加载入ioc的呢?
      在定义引导类的时候,添加的@SpringBootApplication注解是一个组合注解包含了:
    • @SpringBootConfiguration 该注解表示此类是配置类
    • @EnableAutoConfiguration 该注解底层就是@import注解,而这个注解会加载AutoConfigurationImportSelector这个类,通过这个类去加载META-INF/spring.factories这个文件,文件在autoconfig下面,该配置文件中定义了大量的配置类,
      • 当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean,但是有不是所有的类都会被注入ioc容器,这些被spring管理的类在他们的工程中进行了配置文件类,当只有在pom文件中导入了这个类的坐标,才会被注入ioc容器中


      

  • 相关阅读:
    30-Transformation(HDU4578)-区间线段树(复杂)
    87-区间线段树(板子)--那个苑区的人最瘦
    86-区间线段树-模板
    1-2018-3-2小球碰撞
    85-取石子-威佐夫博弈
    83-取石子-尼姆博弈
    82-珠子染色-置换群
    2018.3.29 设计模式之单例模式详解
    2018.3.27 Mac 配置Tomcat
    2018.3.26 Linux下学习命令
  • 原文地址:https://www.cnblogs.com/luckysupermarket/p/13782665.html
Copyright © 2011-2022 走看看