在介绍策略工厂的实现前,我们要先了解spring中beanFactory:
BeanFactory
作为IOC服务的提供者,通过XmlBeanFactory来得到实例
生产Bean的工厂,采用延迟初始化策略(只有在需要某个对象时,才进行初始化和依赖注入);通常会用xml文件来注册并管理各个业务对象之间的依赖关系
DefaultListableBeanFactory实现了BeanFactory接口和BeanDefinitionRegistry接口(负责Bean的注册管理)
属性键值对注入PropertyValue
这里的key:group,value:name
位于beans包下,是bean属性键值对的封装,缓存了对key-value解析相关的信息,避免重复解析
AttributeAccessor
可以访问对象的属性或将属性附加到对象上。
public interface AttributeAccessor {
//增删改查
void setAttribute(String name, @Nullable Object value);
@Nullable
Object getAttribute(String name);
@SuppressWarnings("unchecked")
default <T> T computeAttribute(String name, Function<String, T> computeFunction) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(computeFunction, "Compute function must not be null");
Object value = getAttribute(name);
if (value == null) {
value = computeFunction.apply(name);
Assert.state(value != null,
() -> String.format("Compute function must not return null for attribute named '%s'", name));
setAttribute(name, value);
}
return (T) value;
}
@Nullable
Object removeAttribute(String name);
boolean hasAttribute(String name);
String[] attributeNames();
}
BeanMetadataElement
持有属性信息的对象。
public interface BeanMetadataElement {
@Nullable
default Object getSource() {
return null;
}
}
BeanMetadataAttributeAccessor
实现了 AttributeAccessor和 BeanMetadataElement 两个接口,属性为 BeanMetadataAttribute 对象
public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
@Nullable
private Object source;
public void setSource(@Nullable Object source) {
this.source = source;
}
@Override
@Nullable
public Object getSource() {
return this.source;
}
}
PropertyValue
属性键值对
public class PropertyValue extends BeanMetadataAttributeAccessor implements Serializable {
//属性名称
private final String name;
//属性值
@Nullable
private final Object value;
//属性值是否是optional
private boolean optional = false;
//属性值是否进行了属性转换
private boolean converted = false;
//类型转换后的属性值
@Nullable
private Object convertedValue;
//属性值是否需要进行转换
@Nullable
volatile Boolean conversionNecessary;
//缓存解析后的属性名称
@Nullable
transient volatile Object resolvedTokens;
MutablePropertyValues
PropertyValues的默认实现类是MutablePropertyValues
MutablePropertyValues:
-
内部维护了一个
List<PropertyValue> propertyValueList
,将属性值转换为PropertyValue进行存储
Bean的结构图:
每一个受管的对象,在容器中都会有一个BeanDefinition的实例与之对应,BeanDefinition存储对象的信息,包括: -
对应的对象的class类型,是否抽象类,构造方法参数及其他信息
-
beanName就是实例名
实现策略工厂:
注解StrategyAnnotation
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface StrategyAnnotation {
/**
* 策略类型名称,可以支持多个
*
* @return
*/
String[] name() default "";
/**
* 默认组为: defaultGroup
*
* @return
*/
String group() default "defaultGroup";
/**
* 是否默认类型
*
* @return
*/
boolean isDefault() default false;
}
创建策略工厂实现类
管理所有的方法
/**
* 策略工厂
* 当你使用注解 StrategyAnnotation 在类上面
* 那么会通过 RegisterMapDefinition 去自动创建策略工厂。
*
* 策略工厂的名称就是 StrategyAnnotation 定义的group.
*
* 支持的state 参数,就是 StrategyAnnotation 定义的 name
*
*/
public class StrategyFactory<T> {
//key是策略类型,value是具体策略
Map<String, T> localMap;
public T getObjectByState(String state) {
return localMap.get(state);
}
public T defaultObject(String state) {
T t = localMap.get(state);
if (t == null) {
t = localMap.get(null);
}
return t;
}
public T getObjectThrowException(String state) {
T t = localMap.get(state);
if (t == null) {
throw new IllegalStateException("获取对象失败,状态:" + state);
}
return t;
}
public void setLocalMap(Map<String, T> localMap) {
this.localMap = localMap;
}
public Map<String, T> getLocalMap() {
return Collections.unmodifiableMap(this.localMap);
}
}
RegisterMapDefinition
自动创建策略工厂
- 获取注解的group
- 首次registry这个groupBean
- 获取这个groupBean的BeanDefinition
- 遍历注解的name
- 通过定义的key(localMap)获得PropertyValue属性值
- 首次属性值为空,创建一个PropertyValue(以localMap为key,ManagedMap为value)
- 将localMap这个PropertyValue属性添加到propertyValues中即可
/**
* 策略配置加载器
*/
@Component
public class RegisterMapDefinition implements BeanDefinitionRegistryPostProcessor {
public static final String LOCAL_MAP_PROPERTY = "localMap";
Logger logger = LoggerFactory.getLogger(getClass());
/**
* 本文加载有注解的bean为map 作为策略映射,
*
* @param beanFactory
* @throws BeansException
* @see StrategyAnnotation
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
private void registerGroupMap(BeanDefinitionRegistry registry, StrategyAnnotation strategyAnnotation, String beanName, BeanDefinition beanDefinition) {
String groupBean = strategyAnnotation.group();
if (!registry.containsBeanDefinition(groupBean)) {
RootBeanDefinition strategyFactoryDefinition = new RootBeanDefinition();
strategyFactoryDefinition.setBeanClass(StrategyFactory.class);
registry.registerBeanDefinition(groupBean, strategyFactoryDefinition);
}
BeanDefinition groupBeanDefinition = registry.getBeanDefinition(groupBean);
String[] names = strategyAnnotation.name();
for (String name : names) {
MutablePropertyValues propertyValues = groupBeanDefinition.getPropertyValues();
PropertyValue localMap = propertyValues.getPropertyValue(LOCAL_MAP_PROPERTY);
if (localMap == null) {
localMap = new PropertyValue(LOCAL_MAP_PROPERTY, new ManagedMap<>());
propertyValues.addPropertyValue(localMap);
}
ManagedMap<TypedStringValue, BeanReference> stringObjectManagedMap =
(ManagedMap<TypedStringValue, BeanReference>) localMap.getValue();
stringObjectManagedMap.put(new TypedStringValue(name), new RuntimeBeanReference(beanName));
if (strategyAnnotation.isDefault()) {
stringObjectManagedMap.put(null, new RuntimeBeanReference(beanName));
}
propertyValues.addPropertyValue(localMap);
}
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
String op = "RegisterMapDefinition.postProcessBeanDefinitionRegistry";
logger.info(Logs.op(op).msg("批量创建策略实例").toString());
//获取所有的beanName
String[] strategyAnnotationsArray = registry.getBeanDefinitionNames();
//遍历每个beanName
for (String beanName : strategyAnnotationsArray) {
BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
try {
//获得bean的类名
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName == null) {
continue;
}
//找到类对象
Class<?> clazz = Class.forName(beanClassName);
//获取类对象上的StrategyAnnotations注解
StrategyAnnotations annotation = AnnotationUtils.findAnnotation(clazz, StrategyAnnotations.class);
//有StrategyAnnotations注解的进行注册
if (annotation != null) {
for (StrategyAnnotation strategyAnnotation : annotation.value()) {
registerGroupMap(registry, strategyAnnotation, beanName, beanDefinition);
}
}
StrategyAnnotation strategyAnnotation = AnnotationUtils.findAnnotation(clazz, StrategyAnnotation.class);
if(strategyAnnotation!=null){
registerGroupMap(registry, strategyAnnotation, beanName, beanDefinition);
}
} catch (ClassNotFoundException e) {
logger.debug(Logs.op(op).msg("策略加载器加载指定类不存在").toString(), e);
}
}
}
}