zoukankan      html  css  js  c++  java
  • SpringBoot自动配置原理

    SpringBoot自动配置原理:
        1. Condition接口:
            Condition接口是spring4.0之后提供的接口,增加条件判断功能,用于选择性的创建Bean对象到spring容器中。
        在Condition接口有一个方法:matches(),该方法用于判断,当加入了相关坐标依赖后,返回值为true,没有加入依赖,
        则返回值为false。
        
        2.相关注解说明:
            @Configuration:标记该类是一个配置类
            @Bean:用在方法上,将方法的返回值(一般是Bean)注册给spring容器管理
            @Conditional(OnCondition.class):用在方法上,用于判断,如果类OnCondition中的方法matches()返回值为true,
            则执行下面的代码,否则不执行
            @Import:
                import注解用于导入其他的配置,让spring容器进行加载和初始化。import的注解有以下的几种方式使用:
                1. @Import(User.class):
                    直接导入Bean,注意使用该注解,类User要使用注解@Component注册给spring容器;
                2. @Import(UserConfig.class):
                3. @Import(MyImportSelector.class):导入ImportSelector接口的实现类,实现类中重写方法selectImports(),
                    该方法返回要注册到spring容器中的Bean的全路径,即:
                        return new String[]{"com.itheima.pojo.Role", "com.itheima.pojo.User"};
                4. @Import(MyImportBeanDefinitionRegistrar.class):导入ImportBeanDefinitionRegistrar实现类,重写
                registerBeanDefinitions()方法:
                    @Override
                    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
                        //创建BeanDefiniation
                        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
                        //注册bean 目前只注册User
                        registry.registerBeanDefinition("user",beanDefinition);
                    }
                            
            @SpringBootApplication:
                该注解由以下三个注解所组成:
                1. @SpringbootConfiguration:
                    该注解等价于@Configuration,用于标记该类是一个配置类;
                2. @ComponentScan:
                    该注解用于组件扫描(包扫描),类似于xml中的context-componet-scan,如果不指定扫描路径,
                    那么就扫描该注解修饰的启动类所在的包以及子包。
                3. @EnableAutoConfiguration
                    1.组合了@import注解,导入配置
                    2.使用了@Import的第三种用法,导入ImportSelector接口的实现类,selectImports导入类中的方法中加载配置返回Bean定义的字符数组
                    3.加载META-INF/spring.factories ,获取Bean定义的全路径名返回
                    4.最终返回回去即可
    
                    
        
        需求:
            当加入了jedis依赖后,自动创建User存入spring容器中;没有jedis依赖坐标,则不创建User;
            
        实现:
            1. 创建工程,导入坐标:
                <?xml version="1.0" encoding="UTF-8"?>
                <project xmlns="http://maven.apache.org/POM/4.0.0"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
                    <modelVersion>4.0.0</modelVersion>
    
                    <groupId>com.it</groupId>
                    <artifactId>springboot-condition</artifactId>
                    <version>1.0-SNAPSHOT</version>
    
                    <parent>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-parent</artifactId>
                        <version>2.1.4.RELEASE</version>
                    </parent>
    
                    <dependencies>
                        <!--加入springboot的starter起步依赖-->
                        <dependency>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-starter</artifactId>
                        </dependency>
    
                        <dependency>
                            <groupId>redis.clients</groupId>
                            <artifactId>jedis</artifactId>
                            <version>3.2.0</version>
                        </dependency>
    
                    </dependencies>
    
    
                </project>
            
            2. 创建pojo--User
                package com.it.pojo;
    
                /**
                 * ToDo
                 *
                 * @author Lyle
                 * @date 2020/4/1
                 */
                public class User {
                
                }
            
            3. 创建启动类
                package com.it;
    
                import org.springframework.boot.SpringApplication;
                import org.springframework.boot.autoconfigure.SpringBootApplication;
                import org.springframework.context.ConfigurableApplicationContext;
    
                /**
                 * ToDo
                 *
                 * @author Lyle
                 * @date 2020/4/1
                 */
                @SpringBootApplication
                public class ConditionApplication {
                    public static void main(String[] args) {
                        ConfigurableApplicationContext context = SpringApplication.run(ConditionApplication.class, args);
                        Object user = context.getBean("user");
                        System.out.println(user);
                    }
                }
                
            4. 创建配置类,用于向spring容器中注册对象:
                package com.it.config;
    
                import com.it.condition.OnCondition;
                import com.it.pojo.User;
                import org.springframework.context.annotation.Bean;
                import org.springframework.context.annotation.Conditional;
                import org.springframework.context.annotation.Configuration;
    
                /**
                 * ToDo
                 *
                 * @author Lyle
                 * @date 2020/4/1
                 */
                @Configuration//标记该类是一个配置类
                public class UserConfig {
    
                    //注册Bean--User交给spring来管理
                    //当导入了相关坐标依赖的时候
                    @Bean
                    @Conditional(OnCondition.class)//用于判断,如果OnCondition中的matches()返回值为true,则执行下面的代码,否则不执行
                    public User user(){//注意方法名不能改
    
                        return new User();
                    }
                }
                
            5. 创建类OnCondition,用于判断
                package com.it.condition;
    
                import org.springframework.context.annotation.Condition;
                import org.springframework.context.annotation.ConditionContext;
                import org.springframework.core.type.AnnotatedTypeMetadata;
    
                /**
                 * ToDo
                 *
                 * @author Lyle
                 * @date 2020/4/1
                 */
                public class OnCondition implements Condition {
                    //用于判断,符合条件,返回true,不符合条件,返回false
                    @Override
                    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
                        //jedis坐标存在,返回true
                        try {
                            Class.forName("redis.clients.jedis.Jedis");//执行成功,说明类加载到了,类存在
                        } catch (ClassNotFoundException e) {//否则,说明类不存在
                            e.printStackTrace();
                            return false;
                        }
                        //jedis坐标不存在,返回false
                        return true;
                    }
                }
                
        3. 切换内置的web容器Tomcat
            1. 排除Tomcat的起步依赖:
                <exclusions>
                    <exclusion>
                        <artifactId>spring-boot-starter-tomcat</artifactId>
                        <groupId>org.springframework.boot</groupId>
                    </exclusion>
                </exclusions>
                
            2. 加入其它web容器的依赖:例如:jetty,netty等
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-jetty</artifactId>
                </dependency>
                        
                        
        
    
    
                
    
    
            
        
            
            
  • 相关阅读:
    查询内容在网页里面分页显示+跳页查看
    struts2——通配符
    JavaScript 输出
    oracl函数
    oracle基本用法
    Java之线程处理之二
    java之多线程之一/序列化和反序列化
    错题整理之二
    S2结业考试的第一次测验
    cookie与session的爱恨情仇
  • 原文地址:https://www.cnblogs.com/lyle-liu/p/12618820.html
Copyright © 2011-2022 走看看