概念
IOC:控制反转。从前需要在程序中创建对象实例;现在则通过一个外部的容器统一动态创建
spring IOC 容器中的实例如何动态加载
Condition:只有在特定条件满足时才加载
举例
@ConditionalOnBean
当存在某个实例时才加载
@ConditionalOnClass
当存在某个字节码文件时才加载
@ConditionalOnProperty
当在配置文件中存在某项配置信息时才加载
将这些注解写在类或者方法上,就可以在程序运行时动态加载
自定义动态加载
- 实现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:注解元对象:注解定义的属性值
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
try {
//获取注解定义的属性值 “org.springframework.data.redis.core.RedisTemplate”
Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
//加载字节码文件,如果可以加载则返回true,否则返回false
String[] value = (String[]) map.get("value");
for (String v : value) {
Class<?> cls = Class.forName(v);
}
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
- 自定义注解
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();
}
- 创建User类用于测试
public class User {
}
- 创建加载User实例对象配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//说明这是一个配置类,在启动时会被加载
@Configuration
public class UserConfig {
@Bean
//该注解表示当“org.springframework.data.redis.core.RedisTemplate”存在时创建User实例对象
@ConditionOnClass("org.springframework.data.redis.core.RedisTemplate")
public User user(){
return new User();
}
}
- 测试
@SpringBootApplication
public 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);
}
}