原始注解
@Component
@Component
public class SystemBean 首字母小写的名称:systemBean
@Component("system123")
public class SystemBean 首字母小写的名称:system123
只能在类型使用:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component
@Bean
方法或者注解上使用:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean
使用的方法的类必须可以被spring扫描到
@Component
public class ConditionalConfig {
// bean name 为:WindowsSystemBean
@Bean("WindowsSystemBean")
public SystemBean systemWi() {
return new SystemBean("windows系统","002");
}
// bean name 为方法名:systemWi1
@Bean
public SystemBean systemWi1() {
log.info("ConditionalConfig方法注入 windows实体");
return new SystemBean("windows系统","002");
}
}
@Component衍生注解
下面类都集成了@Service,并重新了value(bean名称可以重命名),他们都具有被Spring扫描的属性。区别是@Controller会扫描其中接口;@Service和@Configuration为了体现功能进行的一种衍生。顾名思义,一个是服务层,一个配置。
定义
功能:
@Controller(“value1”) 相当于给父注解@Component(“value1”) 是可以扫描并被利用的。
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Controller
@Service
@Configuration
经常将所有配置Bean放在***Configuration中使用@Bean方法注入。
在Springboot中有很多***AutoConfiguration,配合已条件注入进行配置。
条件注入
@Conditional
类 或者方法上使用
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
value是实现接口Condition的类。
示例:如果WindowsCondition. matches方法返回为true就创建一个对象,bean名称为system123。
@Conditional(value = WindowsCondition.class)
@Component(value=”system123”)
public class SystemBean {
/**
* 系统名称
*/
private String systemName;
/**
* 系统code
*/
private String systemCode;
}
接口Condition
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
@Slf4j
public class WindowsCondition implements Condition {
/**
* @param conditionContext:判断条件能使用的上下文环境
* @param annotatedTypeMetadata:注解所在位置的注释信息
* @result 返回true 创建Bean; false 不会创建
*/
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
// 获取@Component("system123")中任何数据,需要按照类型名称获取
MultiValueMap<String, Object> attributes = annotatedTypeMetadata.getAllAnnotationAttributes(Component.class.getName());
// 获取value属性的值
Object object = attributes.get("value");
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
//获得当前系统名
String property = environment.getProperty("os.name");
//包含Windows则说明是windows系统,返回true
if (property.contains("Windows")){
log.info("当前操作系统是:Windows");
return true;
}
return false;
}
}
使用场景
类上结合@Component使用
@Conditional(value = WindowsCondition.class)
@Component("system123")
public class SystemBean {
/**
* 系统名称
*/
private String systemName;
/**
* 系统code
*/
private String systemCode;
}
方法上结合@Bean使用
@Slf4j
@Configuration
public class ConditionalConfig {
@Bean("WindowsSystemBean")
@Conditional({WindowsCondition.class})
public SystemBean systemWi() {
log.info("ConditionalConfig方法注入 windows实体");
return new SystemBean("windows系统","002");
}
@Bean("Mac")
@Conditional({MacCondition.class})
public SystemBean systemMac() {
log.info("ConditionalConfig方法注入 mac实体");
return new SystemBean("Mac ios系统","001");
}
}
end ...