zoukankan      html  css  js  c++  java
  • springboot自动装配原理,写一个自己的start

    springboot自动装配原理

    第一次使用springboot的时候,都感觉很神奇。只要加入一个maven的依赖,写几行配置,就能注入redisTemple,rabbitmqTemple等对象。

    这一切要从spring的的@bean@Configuration注解说起
    如果spring扫描到一个类加了@Configuration注解,那么这个类下面的@bean注解的返回对象就会注册到spring的容器里面
    然后就能通过@Autowired注解获取bean
    spring容器

    以springboot里面的RabbitAutoConfiguration为例子,他位于boot.autoconfigure包下面。只要spring容器扫描到这个类,就能把类下面的bean对象注册到容器。
    mqautoconfig

    那么现在的问题是,$color{red}{怎么告诉spring容器@Configuration的类路径}$
    这个就是springboot要做的事。
    springboot启动的时候会扫描所以依赖的jar包下面的META-INF文件夹下面的spring.factories文件。
    然后找这个文件的关键字org.springframework.boot.autoconfigure.EnableAutoConfiguration= ,这个关键字后面的字符串就是告诉spring要加载哪些@Configuration的类
    autoconfig

    所以要写一个自己的start需要做以下几件事##

    1. 创建一个maven工程,写一个自己的@Configuration
    2. 在META-INF文件夹下面创建spring.factories文件,配置自己刚刚的Configuration类路径。
    3. 打包到仓库。
    4. 新建springboot工程引用刚刚的包依赖。

    开始

    一、创建一个maven工程,写一个自己的@Configuration
    我写了一个自己的EujianRedisTemplate类,用来操作redis
    pom文件如下

    <?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.bootstart</groupId>
        <artifactId>eujian-spring-boot-starter</artifactId>
        <version>1.0</version>
        <properties>
            <maven.compiler.target>1.8</maven.compiler.target>
            <maven.compiler.source>1.8</maven.compiler.source>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-autoconfigure</artifactId>
                <version>2.1.0.RELEASE</version>
                <scope>compile</scope>
            </dependency>
    
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.9.0</version>
            </dependency>
        </dependencies>
    </project>
    

    写EujianRedisTemplate类

    import org.springframework.cglib.core.internal.Function;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    
    public class EujianRedisTemplate {
    
        private JedisPool pool;
    
        public EujianRedisTemplate(JedisPool pool) {
            this.pool = pool;
        }
    
        public String getString(String key){
            String value = redisFun(jedis -> {
                return jedis.get(key);
            });
            return value;
        }
    
        public void setString (String key,String object){
            redisFun(jedis -> {
                jedis.set(key,object);
                return null;
            });
        }
    
        public <T>T redisFun (Function<Jedis,T> function){
            Jedis resource = pool.getResource();
            T apply = function.apply(resource);
            resource.close();
            return apply;
        }
    }
    

    EujianProperties用于读取配置

    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties("eujian.redis")
    public class EujianProperties {
    
    
        private String host = "127.0.0.1";
    
    
        private Integer port = 6379;
    
    
        private Integer timeout = 2000;
    
        private String password;
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public Integer getPort() {
            return port;
        }
    
        public void setPort(Integer port) {
            this.port = port;
        }
    
        public Integer getTimeout() {
            return timeout;
        }
    
        public void setTimeout(Integer timeout) {
            this.timeout = timeout;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    

    AutoConfig类

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    @Configuration
    @EnableConfigurationProperties(EujianProperties.class)
    public class AutoConfig {
    
        @Autowired
        private EujianProperties eujianProperties;
    
        @Bean
        public JedisPool jedisPool (){
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxIdle(8);
            config.setMaxTotal(18);
            JedisPool pool = new JedisPool(config, eujianProperties.getHost(), eujianProperties.getPort(), eujianProperties.getTimeout(), eujianProperties.getPassword());
            return pool;
        }
    
    
        @Bean
        public EujianRedisTemplate eujianJedis (JedisPool jedisPool){
            return new EujianRedisTemplate(jedisPool);
        }
    
    }
    

    二、 在META-INF文件夹下面创建spring.factories文件,配置自己刚刚的Configuration类路径。
    在resources下面新建META-INF文件夹,再新建spring.factories文件
    文件内容如下

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.bootstart.maven.AutoConfig
    

    三、执行mvn install打包到本地

    四、新建一个boot工程,pom依赖增加dependency如下

    <dependency>
                <groupId>com.bootstart</groupId>
                <artifactId>eujian-spring-boot-starter</artifactId>
                <version>1.0</version>
            </dependency>
    

    application.properties文件增加配置
    eujian.redis.host=39.108.83.105

    编写单元测试类

    import com.bootstart.maven.EujianRedisTemplate;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class BootstartApplicationTests {
    	@Autowired
    	private EujianRedisTemplate eujianRedisTemplate;
    
    	@Test
    	public void contextLoads() {
    		eujianRedisTemplate.setString("1","qw");
    		String string = eujianRedisTemplate.getString("1");
    		System.out.println(string);
    	}
    }
    

    执行单元测试,EujianRedisTemplate类注入成功

    boot项目地址
    github: https://github.com/hd-eujian/bootstart.git
    码云:https://gitee.com/guoeryyj/bootstart.git

    maven项目地址
    github: https://github.com/hd-eujian/maven-start.git
    码云: https://gitee.com/guoeryyj/maven-start.git

  • 相关阅读:
    js语言基础练习(二)---------------函数的基础知识
    js语言基础练习
    js基本语法总结(一)
    HTML基础知识总结
    参考资料
    css基础知识的复习总结(三)
    css基础知识的复习总结(二)
    css基础知识的复习总结
    旋转数组
    CSS 之 position
  • 原文地址:https://www.cnblogs.com/yeyongjian/p/13390855.html
Copyright © 2011-2022 走看看