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(自定义条件)

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版(一篇文章精通系列)

Spring Boot从入门到精通-项目搭建

Java之Spring入门到精通IDEA版Spring的IoC和DI(一篇文章精通系列)

Java之Spring入门到精通IDEA版Spring的IoC和DI(一篇文章精通系列)

Java之Spring入门到精通IDEA版IoC和DI注解开发(一篇文章精通系列)