Springboot 对象实例是如何动态加载到 IOC 容器的

概念

IOC:控制反转 。从前需要在程序中创建对象实例;现在则通过一个外部的容器统一动态创建
spring IOC 容器中的实例如何动态加载
Condition:只有在特定条件满足时才加载
举例
Springboot 对象实例是如何动态加载到 IOC 容器的

文章插图
【Springboot 对象实例是如何动态加载到 IOC 容器的】 
@ConditionalOnBean
当存在某个实例时才加载
@ConditionalOnClass
当存在某个字节码文件时才加载
@ConditionalOnProperty
当在配置文件中存在某项配置信息时才加载
将这些注解写在类或者方法上 , 就可以在程序运行时动态加载
Springboot 对象实例是如何动态加载到 IOC 容器的

文章插图
 
自定义动态加载
  1. 实现Condition接口自定义筛选条件
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 {/**Condition接口只有一个matches方法context:上下文对象:环境对象、IOC容器对象 , ClassLoader对象metadata:注解元对象:注解定义的属性值*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {try {//获取注解定义的属性值 “org.springframework.data.redis.core.RedisTemplate”Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());//加载字节码文件 , 如果可以加载则返回true , 否则返回falseString[] value = https://www.isolves.com/it/cxkf/kj/2022-10-10/(String[]) map.get("value");for (String v : value) {Class cls = Class.forName(v);}return true;} catch (ClassNotFoundException e) {return false;}}}
  1. 自定义注解
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();}
  1. 创建User类用于测试
public class User {}
  1. 创建加载User实例对象配置类
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;//说明这是一个配置类 , 在启动时会被加载@Configurationpublic class UserConfig {@Bean//该注解表示当“org.springframework.data.redis.core.RedisTemplate”存在时创建User实例对象@ConditionOnClass("org.springframework.data.redis.core.RedisTemplate")public User user(){return new User();}}
  1. 测试
@SpringBootApplicationpublic class SpingbootConditionApplication {public static void main(String[] args) {//接收到加载的配置内容ConfigurableApplicationContext context = SpringApplication.run(SpingbootConditionApplication.class, args);Object user = context.getBean("user");//输出“com.study.boot.User@64469d8”表示已将user这个bean加载到容器System.out.println(user);}}




    推荐阅读