整合RabbitMQ
创建服务提供者
- 引入依赖
<?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>
- 创建启动类
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);
}
}
- 创建发送消息的测试类
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");
}
}
- 创建服务消费者 创建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);
}
}
- 创建监听类
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
- 小结
创建服务的提供者
- 需要一个启动类
- 需要一个测试类,发送消息
- 需要AmqpTemplate.convertAndSend发送信息
- 配置文件需要配置RabbitMQ的信息:IP地址、端口号、用户名、密码、虚拟主机
- 需要一个初始化队列的类,主要的作用就是将队列写入到Bean里
创建服务的消费者
- 需要创建启动类
- 需要监听类,监听消息,主要使用@RabbitListener注解
- 配置文件需要配置RabbitMQ的信息:IP地址、端口号、用户名、密码、虚拟主机
整合Redis
创建模块,引入依赖
- 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>
- 创建启动类
ApplicationRunner.java
@SpringBootApplication
public class ApplicationRun {
public static void main(String[] args) {
SpringApplication.run(ApplicationRun.class, args);
}
}
- 创建测试类
@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增加的条件判断功能,通过这个注解可以实现选择性的创建Bean的操作
创建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和环境变量中的
ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(ApplicationCoRunner.class, args);
Object redisTemplate = configurableApplicationContext.getBean("redisTemplate");
System.out.println(redisTemplate);
}
}
使用Condition注释
创建一个MyCondition类,实现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();
}
}
动态加载Bean
- 创建一个注解类
/**
* @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:判断环境中是否有对应的字节码文件才初始化Bean
- ConditionalOnMissingBean:判断环境中是否有对应的Bean才初始化Bean
注解@Enable
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的,而其底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载
springboot工程是否可以直接获取jar包中定义的bean?
案例背景:创建两个模块,一个是springboot_enable 一个是springboot_enable_other
需求:在springboot_enable里通过@Enable注解加载User这个Bean,而User这个Bean是在springboot_enable_other模块中
创建两个模块
- 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中创建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实现类,一般用于加载配置文件中的类
- 导入ImportBeanDefinitionRegistrar实现类
导入ImportSelector
- 创建实现类
- 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实现类
- 创建实现类
- 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>
- 创建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());
}
}
}
- 创建一个新的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监控
- 创建模块 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: "*"
server.port:端口号
info.name\info.class:监控中心里的配置文件info下的内容
management.endpoint.health.show-details:在健康中心下监控你的程序运行状态
management.endpoints.web.exposure.include:"*" 开启所有的监控内容
info: http://localhost:8090/actuator/info 读取的是配置文件中info的内容
health:http://localhost:8090/actuator/health 读取当前应用状态
beans:http://localhost:8090/actuator/beans 读取所有bean
springboot可视化监控
springboot_admin
- 创建一个模块
<?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
加入客户端
- 创建模块 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: "*"