SpringBoot(二) 高級以及原理解釋

整合RabbitMQ

創(chuàng)建服務提供者

  • 引入依賴
<?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>cn.itcast</groupId>
    <artifactId>rabbitmq_provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
</project>
  • 創(chuàng)建啟動類
package com.probuing.sb2.rabbitmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author wangxin
 * @date 2020/1/12 15:49
 * @description: TODO
 * GOOD LUCK!
 */
@SpringBootApplication
public class ApplicationRun {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationRun.class, args);
    }
}

  • 創(chuàng)建發(fā)送消息的測試類
    ProviderTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProviderTest {

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Test
    public void sendMsg() {
        amqpTemplate.convertAndSend("", "sb2_message", "這是一條message");

    }
}
  • 配置文件
    主要配置RabbitMQ的ip地址、端口號、虛擬主機、用戶名、密碼
server:
  port: 8080
spring:
  rabbitmq:
    host: 127.0.0.1
    username: admin
    password: admin
    virtual-host: sb2
    port: 5672
    
  • 隊列類
    MQConfig.java
@Component
public class MQConfig {
    @Bean
    public Queue queue(){
        return new Queue("sb2_mq");
    }
}
  • 創(chuàng)建服務消費者 創(chuàng)建module springboot_rabbitmq_consumer
  • 引入依賴
<?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">
    <parent>
        <artifactId>SpringBoot2</artifactId>
        <groupId>com.probuing.sb2</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot2_rabbitmq_consumer</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

</project>
  • 啟動類
    ApplicationConsumerRun.java
@SpringBootApplication
public class ApplicationConsumerRun {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationConsumerRun.class, args);
    }
}

  • 創(chuàng)建監(jiān)聽類
    MyListener.java
@Component
public class MyListener {
    @RabbitListener(queues = "sb2_mq")
    public void receiveMsg(String msg) {
        System.out.println("listener收到信息" + msg);
    }
}
  • 配置文件
    applicaiton.yml
spring:
  rabbitmq:
    host: 127.0.0.1
    username: admin
    password: admin
    virtual-host: heima118
    port: 5672
server:
  port: 8081
  • 小結(jié)

創(chuàng)建服務的提供者

  • 需要一個啟動類
  • 需要一個測試類,發(fā)送消息
  • 需要AmqpTemplate.convertAndSend發(fā)送信息
  • 配置文件需要配置RabbitMQ的信息:IP地址、端口號、用戶名、密碼、虛擬主機
  • 需要一個初始化隊列的類,主要的作用就是將隊列寫入到Bean里

創(chuàng)建服務的消費者

  • 需要創(chuàng)建啟動類
  • 需要監(jiān)聽類,監(jiān)聽消息,主要使用@RabbitListener注解
  • 配置文件需要配置RabbitMQ的信息:IP地址、端口號、用戶名、密碼、虛擬主機

整合Redis

創(chuàng)建模塊,引入依賴

  • pom.xml
<?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">
    <parent>
        <artifactId>SpringBoot2</artifactId>
        <groupId>com.probuing.sb2</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot2_redis</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
</project>
  • 創(chuàng)建啟動類
    ApplicationRunner.java
@SpringBootApplication
public class ApplicationRun {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationRun.class, args);
    }
}
  • 創(chuàng)建測試類
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApplicationRun.class)
public class RedisTest {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Test
    public void redisTest() {
        stringRedisTemplate.opsForValue().set("redis_sb", "testRedis");
        String redis_sb = stringRedisTemplate.opsForValue().get("redis_sb");
        System.out.println(redis_sb);
    }
}

注解:@Condition

Condition:Condition是在Spring4.0增加的條件判斷功能,通過這個注解可以實現(xiàn)選擇性的創(chuàng)建Bean的操作

創(chuàng)建Condition模塊

  • 引入依賴
    pom.xml
<?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">
    <parent>
        <artifactId>SpringBoot2</artifactId>
        <groupId>com.probuing.sb2</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot2_condition</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>
</project>
  • 啟動類
    ApplicationRunner.java
@SpringBootApplication
public class ApplicationCoRunner {
    public static void main(String[] args) {
        //ConfigurableApplicationContext是Spring的IOC容器,可以通過容器獲取bean和環(huán)境變量中的
        ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(ApplicationCoRunner.class, args);
        Object redisTemplate = configurableApplicationContext.getBean("redisTemplate");
        System.out.println(redisTemplate);
    }
}

使用Condition注釋

創(chuàng)建一個MyCondition類,實現(xiàn)Condition接口,接口中有一個方法,返回boolean
MyCondition.java

/**
 * @author wangxin
 * @date 2020/1/12 17:26
 * @description: TODO
 * GOOD LUCK!
 */
public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        boolean flag = true;
        try {
            Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            flag = false;
        }
        return flag;
    }
}

UserConfig類

@Configuration
public class UserConfig {
    @Bean
    @Conditional(MyCondition.class)
    public User user() {
        return new User();
    }
}

動態(tài)加載Bean

  • 創(chuàng)建一個注解類
/**
 * @author wangxin
 * @date 2020/1/12 17:38
 * @description: TODO
 * GOOD LUCK!
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyCondition.class)
public @interface MyConditional {
    String[] value();
}
  • 修改MyCondition.java
public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        boolean flag = true;
        Map<String, Object> map = annotatedTypeMetadata.getAnnotationAttributes(MyConditional.class.getName());
        String[] strings = (String[]) map.get("value");
        try {
            for (String string : strings) {
                Class.forName(string);

            }
        } catch (ClassNotFoundException e) {
            flag = false;
        }
        return flag;
    }
}

SpringBoot常用條件注解

  • ConditionalOnProperty:判斷配置文件中是否有對應的屬性和值才初始化Bean
  • ConditionalOnClass:判斷環(huán)境中是否有對應的字節(jié)碼文件才初始化Bean
  • ConditionalOnMissingBean:判斷環(huán)境中是否有對應的Bean才初始化Bean

注解@Enable

SpringBoot中提供了很多Enable開頭的注解,這些注解都是用于動態(tài)啟用某些功能的,而其底層原理是使用@Import注解導入一些配置類,實現(xiàn)Bean的動態(tài)加載

springboot工程是否可以直接獲取jar包中定義的bean?

案例背景:創(chuàng)建兩個模塊,一個是springboot_enable 一個是springboot_enable_other
需求:在springboot_enable里通過@Enable注解加載User這個Bean,而User這個Bean是在springboot_enable_other模塊中

創(chuàng)建兩個模塊

  • springboot_enable
  • springboot_enable_other
  • 在enable模塊中加入enable_other依賴
  • pom.xml
 <dependency>
            <groupId>com.probuing.sb2</groupId>
            <artifactId>springboot_enable_other</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

在springboot_enable_other中創(chuàng)建User、UserConfig(配置類)

  • UserConfig.java
@Configuration
public class UserConfig {
    @Bean
    public User user() {
        return new User();
    }
}
  • User.java
public class User {
}

加載UserBean

方式一:擴大掃描包范圍:

在Enable啟動類里增加ComponentScan

@SpringBootApplication
@ComponentScan("com.probuing.sb2.domain")
public class EnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(EnableApplication.class, args);
        //獲取user
        Object user = context.getBean("user");
        System.out.println(user);
    }
}

方式二:導入User類

  • EnableApplication.java
@SpringBootApplication
//@ComponentScan("com.probuing.sb2.domain")
@Import(User.class)
public class EnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(EnableApplication.class, args);
        //從Ioc容器中獲取map集合
        Map<String, User> map = context.getBeansOfType(User.class);
        User user = map.get("com.probuing.sb2.domain.User");
        System.out.println(user);
    }
}

注意
直接導入User類,spring容器導入bean之后取了一個名字,這個名字是bean的全限定名稱,所以可以通過類型獲取Bean

三 導入配置類

  • EnableApplicaiton.java
@SpringBootApplication
@Import(UserConfig.class)
public class EnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(EnableApplication.class, args);
        Object user = context.getBean("user");
        System.out.println(user);
    }
}

四 通過Enable注解

在spring_enable_other中自定義一個注解

  • EnableUser.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)
public @interface EnableUser {
}

啟動類

  • EnableApplication.java
@SpringBootApplication
@EnableUser
public class EnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(EnableApplication.class, args);
        Object user = context.getBean("user");
        System.out.println(user);
    }
}

@Import注解

@Enable*底層依賴于@Import注解導入一些類,使用@Import導入的類會被Spring加載到IOC容器中。而@Import提供4種用法

  • 導入Bean
  • 導入配置類
  • 導入ImportSelector實現(xiàn)類,一般用于加載配置文件中的類
  • 導入ImportBeanDefinitionRegistrar實現(xiàn)類

導入ImportSelector

  • 創(chuàng)建實現(xiàn)類
    • MyImportSelector.java
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.probuing.sb2.domain.User"};
    }
}
  • 修改啟動類
    • EnableApplication.java
@SpringBootApplication
@Import(MyImportSelector.class)
public class EnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(EnableApplication.class, args);
        Object user = context.getBean("user");
        System.out.println(user);
    }
}

導入ImportBeanDefinitionRegistrar實現(xiàn)類

  • 創(chuàng)建實現(xiàn)類
    • MyImportBeanDefinitionRegister.java
public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata,
                                        BeanDefinitionRegistry beanDefinitionRegistry) {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
        beanDefinitionRegistry.registerBeanDefinition("user",beanDefinition);
        
    }
}
  • 修改啟動類
    ·* EnableApplication.java
@SpringBootApplication
@Import(MyImportBeanDefinitionRegister.class)
public class EnableApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(EnableApplication.class, args);
//        Object user = context.getBean(User.class);
        Object user = context.getBean("user");
        System.out.println(user);
    }
}

自定義Starter

模擬Mybatis的Starter加載過程

  • redis-spring-boot-autoconfigure

  • redis-spring-boot-starter

  • redis-spring-boot-starter引入依賴

<dependencies>

        <dependency>
            <groupId>com.probuing.sb2</groupId>
            <artifactId>redis-spring-boot-autoconfigure</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
  • redis-spring-boot-autoconfigure 引入依賴
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0</version>
        </dependency>
  • 創(chuàng)建RedisAutoConfigure
    autoconfigure模塊
    • RedisAutoConfigure.java
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfig {
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisAutoConfig {
    @Bean
    public Jedis jedis(RedisProperties redisProperties) {
        return new Jedis(redisProperties.getHost(), redisProperties.getPort());
    }
}
}
  • 創(chuàng)建一個新的springboot模塊
    • 引入依賴
 <dependencies>

        <dependency>
            <groupId>com.probuing.sb2</groupId>
            <artifactId>redis-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  • 啟動類
@SpringBootApplication
public class MyRedisRun {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(MyRedisRun.class);
        Jedis jedis = (Jedis) context.getBean("jedis");
        jedis.set("probuing", "abc");
        String probuinhg = jedis.get("probuing");
        System.out.println(probuinhg);
    }
}

springboot監(jiān)控

  • 創(chuàng)建模塊 springboot_actuator
  • 引入依賴
    • pom.xml
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>
  • 配置文件
server:
  port: 8090
info:
  name: heima118
  class: springboot
management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: "*"

springboot可視化監(jiān)控

springboot_admin

  • 創(chuàng)建一個模塊
<?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 https://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.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.itcast</groupId>
    <artifactId>springboot_admin</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_admin</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.2.1</spring-boot-admin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>de.codecentric</groupId>
                <artifactId>spring-boot-admin-dependencies</artifactId>
                <version>${spring-boot-admin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 啟動類
@SpringBootApplication
@EnableAdminServer
public class AdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class, args);
    }
}

注意
這里要添加@EnableAdminServer,開啟一個admin服務,主要是管理所有在admin里注冊的服務

  • 配置文件
server.port=8088

加入客戶端

  • 創(chuàng)建模塊 springboot_myredis
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.1.3</version>
</dependency>
  • 客戶端的配置文件
#在admin服務中進行注冊,url指向的是admin對應的地址
spring:
  boot:
    admin:
      client:
        url: http://localhost:8088

#顯示所有的健康信息
management:
  endpoint:
    health:
      show-details: always
      
  #顯示所有的信息    
  endpoints:
    web:
      exposure:
        include: "*"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容