Java之Spring Boot入门到精通IDEA版SpringBoot原理分析,SpringBoot监控(一篇文章精通系列)下
Posted 蓝盒子itbluebox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之Spring Boot入门到精通IDEA版SpringBoot原理分析,SpringBoot监控(一篇文章精通系列)下相关的知识,希望对你有一定的参考价值。
目录 | |
---|---|
Java之Spring Boot入门到精通【IDEA版】(一篇文章精通系列)【上】 | |
Java之Spring Boot入门到精通【IDEA版】SpringBoot整合其他框架【Junit,Redis,MyBatis】(一篇文章精通系列)【中】 | |
Java之Spring Boot入门到精通【IDEA版】SpringBoot原理分析,SpringBoot监控(一篇文章精通系列)【下】 |
Java之Spring Boot入门到精通【IDEA版】SpringBoot原理分析
- 一、SpringBoot自动配置
- 1、Condition(自定义条件)
- 2、Condition(条件)动态实现
- 3、切换内置web服务器
- 4、`@Enable*` 注解
- 5、`@lmport`注解
- 6、`@EnableAutoConfiguration`注解
- 7、自定义starter步骤分析
- (1)创建`redis-spring-boot-autoconfigure`模块
- (2)创建`redis-spring-boot-starter`模块,依赖`redis-spring-boot-autoconfigure`的模块
- (3)修改创建好的两个模块对其进行瘦身
- (3)在`redis-spring-boot-autoconfigure`模块中初始化Jedis的Bean。并定义`META-INF/spring.factories`文件
- (4)在测试模块中引入自定义的`redis-starter`依赖,测试获取Jedis的Bean,操作redis。
- (5)操作上述获取到的Jedis
- (6)编写配置文件设置redis的属性
- 二、SpringBoot监听机制
- 三、SpringBoot启动流程分析
- 四、SpringBoot监控
一、SpringBoot自动配置
1、Condition(自定义条件)
Condition是在Spring 4.0增加的条件判断功能,通过这个可以功能可以实现选择性的创建Bear操作。
SpringBoot是如何知道要创建哪个Bean的?比如SpringBoot是如何知道要创建RedisTemplate的?
(1)搭建工程
(2)获取Bean,redisTemplate
package cn.itbluebox.springbootcondition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringbootConditionApplication {
public static void main(String[] args) {
//启动SpringBoot的应用,返回Spring的IOC容器
ConfigurableApplicationContext context
= SpringApplication.run(SpringbootConditionApplication.class, args);
//1、获取Bean,redisTemplate
Object bean = context.getBean("redisTemplate");
System.out.println(bean);
}
}
- 运行测试
运行报错因为,没有bean是叫redisTemplate
(3)引入redis的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 重新运行测试
(4)在Spring的IOC容器中有一个User的Bean,
1)创建User相关内容
- 创建UserConfig配置类
package cn.itbluebox.springbootcondition.config;
import cn.itbluebox.springbootcondition.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
@Bean
public User user(){
return new User();
}
}
- 获取刚刚创建的User,修改SpringbootConditionApplication
package cn.itbluebox.springbootcondition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringbootConditionApplication {
public static void main(String[] args) {
//启动SpringBoot的应用,返回Spring的IOC容器
ConfigurableApplicationContext context
= SpringApplication.run(SpringbootConditionApplication.class, args);
/*
1、获取Bean,redisTemplate
Object bean = context.getBean("redisTemplate");
System.out.println(bean);
*/
Object user = context.getBean("user");
System.out.println(user);
}
}
- 运行测试
2)现要求:导入Jedis坐标后,加载该Bean,没导入,则不加载
- 创建ClassCondition
package cn.itbluebox.springbootcondition.condtion;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class ClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return false;
}
}
- 修改UserConfig
现在这ClassCondition返回的是false所以不会创建user对应的Bean,只有返回true才会创建user对应的bean
package cn.itbluebox.springbootcondition.config;
import cn.itbluebox.springbootcondition.condtion.ClassCondition;
import cn.itbluebox.springbootcondition.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
@Bean
@Conditional(ClassCondition.class)//现在这ClassCondition返回的是false所以不会创建user对应的Bean
public User user(){
return new User();
}
}
-
运行测试
-
运行报错,没有找到user对应的Bean
-
修改ClassCondition将返回值修改为true
package cn.itbluebox.springbootcondition.condtion;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class ClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return true;
}
}
-
运行测试
user对应的Bean创建成功
-
引入Jedis坐标
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
- 完成需求继续修改ClassCondition
package cn.itbluebox.springbootcondition.condtion;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class ClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//1、需求:导入Jedis坐标后,加载该Bean
//2、思路:判断redis.clients.jedis.Jedis.class 文件是否存在
boolean flag = true;
try {
//如果forName可以加载到对应Jedis字节码那么说明引入了Jedis的依赖
Class<?> cls = Class.forName("redis.clients.jedis.Jedis");
} catch (ClassNotFoundException e) {
flag = false;
e.printStackTrace();
}
return flag;
}
}
- 运行测试
- 可以获取到因为,引入了Jedis依赖
- 删除Jedis的依赖
- 再次运行
- 运行报错,并且没有创建user对应的bean
2、Condition(条件)动态实现
- 将类的判断定义为动态的。判断哪个字节码文件存在可以动态指定。
(1)创建ConditionOnClass (自定义注解)
package cn.itbluebox.springbootcondition.condtion;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ClassCondition.class)
public @interface ConditionOnClass {
String[] value();
}
(2)修改UserConfig
package cn.itbluebox.springbootcondition.config;
import cn.itbluebox.springbootcondition.condtion.ClassCondition;
import cn.itbluebox.springbootcondition.condtion.ConditionOnClass;
import cn.itbluebox.springbootcondition.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserConfig {
@Bean
// @Conditional(ClassCondition.class)//现在这ClassCondition返回的是false所以不会创建user对应的Bean
@ConditionOnClass("redis.clients.jedis.Jedis")
public User user(){
return new User();
}
}
- 运行测试
(3)使用导入的指定坐标
- 修改ClassCondition
package cn.itbluebox.springbootcondition.condtion;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Map;
public class ClassCondition implements Condition {
/*
context:上下文对象。用于获取一些环境,IOC容器,ClassLoader对象
metadata:注解元对象。可以用于获取注解定义的属性值。
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//需求:导入通过注解属性值value指定的坐标
//获取注解属性值 value
Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
//System.out.println(map);
String[] value = (String[])map.get("value");
boolean flag = true;
try {
for(String className : value){
//如果forName可以加载到对应Jedis字节码那么说明引入了Jedis的依赖
Class<?> cls = Class.forName(className);
}
} catch (ClassNotFoundException e) {
flag = false;
e.printStackTrace();
}
return flag;
}
}
- 运行测试
(4)判断其他的坐标
- 修改pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
- 修改UserConfig
- 使用User对象必须引入fastjson的坐标
package cn.itbluebox.springbootcondition.config;
import cn.itbluebox.springbootcondition.condtion.ConditionOnClass;以上是关于Java之Spring Boot入门到精通IDEA版SpringBoot原理分析,SpringBoot监控(一篇文章精通系列)下的主要内容,如果未能解决你的问题,请参考以下文章
Java之Spring Boot入门到精通IDEA版SpringBoot整合其他框架Junit,Redis,MyBatis(一篇文章精通系列)中
Java之Spring AOP入门到精通IDEA版(一篇文章精通系列)
Java之Spring入门到精通IDEA版Spring的IoC和DI(一篇文章精通系列)