zoukankan      html  css  js  c++  java
  • spring学习笔记(六)自定义spring-boot-starter(2)

    上篇文章我们主要讲了spring自动装配的原理,我们知道了springboot在启动的时候会自动去读.factories文件,在factories文件中,autoConfiguration对应的就是我们程序启动时自己预加载的类,另外我也提到了另外一个比较核心的注解,即@ConditionOnxxx。详情点击https://blog.csdn.net/qq_41907991/article/details/88704448


    这篇文章我们主要分析下@ConditionOnxxx注解,以及自己实现一个starter。下面开始分析我们的@ConditionOnxxx注解。先看代码:

    我们以@ConditionalOnMissingBean这个注解来分析原理:

    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Conditional(OnBeanCondition.class)
    public @interface ConditionalOnMissingBean {....}

    很明显,上面的核心注解就是@Conditional注解,我们接下来分析这个注解,直接上代码看效果

    package com.study.spring.condition.condition;
    
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    /**
     * @Author: dmz
     * @Description:
     * @Date: Create in 23:16 2019/3/25
     */
    public class CatCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().getProperty("what").equals("cat");
        }
    }
    
    package com.study.spring.condition.condition;
    
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    /**
     * @Author: dmz
     * @Description:
     * @Date: Create in 23:16 2019/3/25
     */
    public class DogCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().getProperty("what").equals("dog");
        }
    }
    

    上面这两个类,是我自定义的两个条件

    package com.study.spring.condition.model;
    
    import com.study.spring.condition.condition.CatCondition;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.stereotype.Component;
    
    /**
     * @Author: dmz
     * @Description:
     * @Date: Create in 23:19 2019/3/25
     */
    @Component
    @Conditional({CatCondition.class})
    public class Cat {
        public Cat(){
            System.out.println("猫来了,喵喵喵~~");
        }
    }
    
    package com.study.spring.condition.model;
    
    import com.study.spring.condition.condition.DogCondition;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.stereotype.Component;
    
    /**
     * @Author: dmz
     * @Description:
     * @Date: Create in 23:18 2019/3/25
     */
    @Component
    @Conditional({DogCondition.class})
    public class Dog {
        public Dog(){
            System.out.println("dog 来了,汪汪汪~~~");
        }
    }
    

    主要是为了通过条件控制我们这两个类的加载

    what:cat
    

    这是配置文件中的内容

    package com.study.spring.condition;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class ConditionApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConditionApplication.class, args);
        }
    
    }
    

    这是启动类

    启动程序,可以看到程序打印:

    猫来了,喵喵喵~~

    经过上面的程序我相信大家对这个@conditional注解已经有了一定的了解

    接下来我们来实现我们的自定义starter

    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>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.study.spring</groupId>
        <artifactId>starter</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>myAutoconfig-spring-boot-starter</name>
        <description>Demo project for Spring Boot</description>
        <packaging>jar</packaging>
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-autoconfigure</artifactId>
            </dependency>
    
            <!--为了生成spring-configuration-metadata.json-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    整体项目结构如下

    package com.study.spring.starter.AutoConfig;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    /**
     * @author dmz
     * @date Create in 22:06 2019/3/23
     */
    @Data
    @ConfigurationProperties(prefix = "config")
    public class Config {
        private String name;
        private Integer age;
    }
    
    package com.study.spring.starter.AutoConfig;
    
    import com.study.spring.starter.service.MyService;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author dmz
     * @date Create in 21:24 2019/3/23
     */
    @Configuration
    @EnableConfigurationProperties(Config.class)
    @ConditionalOnClass(MyService.class)
    public class MyAutoConfig {
    
        @Bean
        @ConditionalOnMissingBean(MyService.class)
        public MyService getMyService() {
            return new MyService();
        }
    }
    
    package com.study.spring.starter.service;
    
    import com.study.spring.starter.AutoConfig.Config;
    import org.springframework.beans.factory.annotation.Autowired;
    
    /**
     * @author dmz
     * @date Create in 21:53 2019/3/23
     */
    public class MyService {
    
        @Autowired
        private Config config;
    
        public void say() {
            System.out.println("自定义的starter来了,say:" + config.getName());
        }
    }
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    /**
     *保留启动类,主要是为了执行maven的命令,
     * 打包到我们的本地仓库
     */
    @SpringBootApplication
    public class StarterApplication{
        public static void main(String[] args) {
            SpringApplication.run(StarterApplication.class, args);
        }
    
    }
    

    spring.factories文件如下:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.study.spring.starter.AutoConfig.MyAutoConfig

    测试代码如下:

    <?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>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.study.spring</groupId>
        <artifactId>starter-test</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>starter-test</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
             <!--引入我们的依赖-->
            <dependency>
                <groupId>com.study.spring</groupId>
                <artifactId>starter</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    启动类:

    package com.study.spring.startertest;
    
    import com.study.spring.starter.service.MyService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class StarterTestApplication implements ApplicationRunner {
    
        @Autowired
        private MyService myService;
    
        public static void main(String[] args) {
            SpringApplication.run(StarterTestApplication.class, args);
        }
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            myService.say();
        }
    }
    

    我们在测试项目中加了配置信息

    config.name=zhangsan
    

    运行结果如下:

      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.1.3.RELEASE)
    
    2019-03-27 00:09:52.995  INFO 19468 --- [           main] c.s.s.s.StarterTestApplication           : Starting StarterTestApplication on DESKTOP-N88SU6M with PID 19468 (C:UsersdellDesktopspring-masterstarter-test	argetclasses started by dell in C:UsersdellDesktopspring-master)
    2019-03-27 00:09:52.999  INFO 19468 --- [           main] c.s.s.s.StarterTestApplication           : No active profile set, falling back to default profiles: default
    2019-03-27 00:09:53.416  INFO 19468 --- [           main] c.s.s.s.StarterTestApplication           : Started StarterTestApplication in 0.722 seconds (JVM running for 1.243)
    自定义的starter来了,say:zhangsan
    
    Process finished with exit code 0

    验证成功~~

    项目github地址:https://github.com/daimingzhi/spring.git

  • 相关阅读:
    VS学习笔记2
    VS学习笔记
    分享几个有趣的小程序
    关于类型的转换(抄来的 ,留着,感觉有用。)
    现在觉得IT还挺有意思
    DataGrid 查出一个列 按要求显示格式 例如:操作人(地点)
    WPF DataGrid 列显示0,-1(作废、删除)状态,1,2(支出、收入)类型,操作人(在其他表中),如何转换格式。
    WPF DataGrid中鼠标双击某一列,弹出窗体作为(增加、修改、详细)按钮的快捷键。
    “指定的参数已超出有效值的范围”在【 parameterUpdate.Add(new OracleParameter("STATUS", 0));】报错
    WPF StoreDataSetPaginator
  • 原文地址:https://www.cnblogs.com/daimzh/p/12854471.html
Copyright © 2011-2022 走看看