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

  • 相关阅读:
    poj 3321 Apple Tree
    hdu 1520 Anniversary party
    Light OJ 1089 Points in Segments (II)
    Timus 1018 Binary Apple Tree
    zoj 3299 Fall the Brick
    HFUT 1287 法默尔的农场
    Codeforces 159C String Manipulation 1.0
    GraphQL + React Apollo + React Hook 大型项目实战(32 个视频)
    使用 TypeScript & mocha & chai 写测试代码实战(17 个视频)
    GraphQL + React Apollo + React Hook + Express + Mongodb 大型前后端分离项目实战之后端(19 个视频)
  • 原文地址:https://www.cnblogs.com/yeyongjian/p/13390855.html
Copyright © 2011-2022 走看看