自动装配
Condition:
Condition内置方法:
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)
,返回值为布尔型
重写matches方法的类:SpringBootCondition
等
SpringBootCondition
:springboot自带的实现类
public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String classOrMethodName = getClassOrMethodName(metadata);
try {
ConditionOutcome outcome = this.getMatchOutcome(context, metadata);
this.logOutcome(classOrMethodName, outcome);
this.recordEvaluation(context, classOrMethodName, outcome);
return outcome.isMatch();
} catch (NoClassDefFoundError var5) {
throw new IllegalStateException("Could not evaluate condition on " + classOrMethodName + " due to " + var5.getMessage() + " not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)", var5);
} catch (RuntimeException var6) {
throw new IllegalStateException("Error processing condition on " + this.getName(metadata), var6);
}
}
正式:
简易实现上面代码逻辑
创建类Guser类,
方法上添加注解@ConditionOnclass(“hunter”):表示能够查询指定的Bean对象则创建方法中的创建Bean,否则报错
package com.example.service.service;
import com.example.controller.conditionOnclass;
import com.example.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Guser {
@conditionOnclass("hunter")
@Bean
public User user(){
return new User();
}
}
}
conditionOnclass注解接口
注解@conditionOnclass接口:指定范围,存在时间,文档,@Conditional
A注解上的B注解可以作用到A注解正在注解的方法上
package com.example.controller;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(myConditional.class)
public @interface conditionOnclass {
String[] value();
}
自定义一个Condition演示原理的类:创建一个实现了Condition接口的类
通过反射
conditionOnclass.class.getName()
获得指定注解下面定义的属性的值,获取成功则返回true,失败则false
myConditional类:实现Condition接口
package com.example.controller;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Map;
public class myConditional implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获得指定注解上面的参数值(即jar包,且可能有多个)
Map<String,Object> map= metadata.getAnnotationAttributes(conditionOnclass.class.getName());
String[] strings=(String[])map.get("value");
try{
// 遍历出来jar包,然后通过反射进行获取,如果没有获取到就进行返回false的处理
for (String className: strings
) {
Class<?> aClass=Class.forName(className);
}
}catch (ClassNotFoundException e){
return false;
}
return true;
}
}
思路:
- 注解接口
conditionOnclass
加在Guer
中的public User user(){}
方法上,只有当此注解中传入的参数(spring容器中的bean的id)存在时,即其返回值为true时,该方法的bean才能注册成功- ture详解:注解
conditionOnclass
接口中添加注解@Conditional(myConditional.class)
其中参数为自定义实现Condition接口的实现类,其中实现了matches()
方法,实现了逻辑:通过反射查询当前传进来的bean的id,查询成功返回true,反之false,如此Guser
中方法上的@conditonOnclass
注解就根据返回的true或者false进行操作