国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計模式-策略工廠

這篇具有很好參考價值的文章主要介紹了設(shè)計模式-策略工廠。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在介紹策略工廠的實現(xiàn)前,我們要先了解spring中beanFactory:

BeanFactory

作為IOC服務(wù)的提供者,通過XmlBeanFactory來得到實例

生產(chǎn)Bean的工廠,采用延遲初始化策略(只有在需要某個對象時,才進行初始化和依賴注入);通常會用xml文件來注冊并管理各個業(yè)務(wù)對象之間的依賴關(guān)系

DefaultListableBeanFactory實現(xiàn)了BeanFactory接口和BeanDefinitionRegistry接口(負責(zé)Bean的注冊管理)
設(shè)計模式-策略工廠

屬性鍵值對注入PropertyValue

這里的key:group,value:name

位于beans包下,是bean屬性鍵值對的封裝,緩存了對key-value解析相關(guān)的信息,避免重復(fù)解析

設(shè)計模式-策略工廠

  • AttributeAccessor 可以訪問對象的屬性或?qū)傩愿郊拥綄ο笊稀?/li>
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 實現(xiàn)了 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;
	//屬性值是否進行了屬性轉(zhuǎn)換
	private boolean converted = false;
	//類型轉(zhuǎn)換后的屬性值
	@Nullable
	private Object convertedValue;
	//屬性值是否需要進行轉(zhuǎn)換
	@Nullable
	volatile Boolean conversionNecessary;
	//緩存解析后的屬性名稱
	@Nullable
	transient volatile Object resolvedTokens;

MutablePropertyValues

設(shè)計模式-策略工廠

PropertyValues的默認實現(xiàn)類是MutablePropertyValues

MutablePropertyValues:

  • 內(nèi)部維護了一個List<PropertyValue> propertyValueList,將屬性值轉(zhuǎn)換為PropertyValue進行存儲
    Bean的結(jié)構(gòu)圖:
    設(shè)計模式-策略工廠
    每一個受管的對象,在容器中都會有一個BeanDefinition的實例與之對應(yīng),BeanDefinition存儲對象的信息,包括:

  • 對應(yīng)的對象的class類型,是否抽象類,構(gòu)造方法參數(shù)及其他信息

  • beanName就是實例名

實現(xiàn)策略工廠:

注解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;
}

創(chuàng)建策略工廠實現(xiàn)類

管理所有的方法

/**
 * 策略工廠
 * 當你使用注解 StrategyAnnotation 在類上面
 * 那么會通過 RegisterMapDefinition 去自動創(chuàng)建策略工廠。
 *
 * 策略工廠的名稱就是 StrategyAnnotation 定義的group.
 *
 * 支持的state 參數(shù),就是 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("獲取對象失敗,狀態(tài):" + state);
        }
        return t;
    }

    public void setLocalMap(Map<String, T> localMap) {
        this.localMap = localMap;
    }

    public Map<String, T> getLocalMap() {
        return Collections.unmodifiableMap(this.localMap);
    }
}

RegisterMapDefinition

自動創(chuàng)建策略工廠文章來源地址http://www.zghlxwxcb.cn/news/detail-500803.html

  1. 獲取注解的group
  2. 首次registry這個groupBean
  3. 獲取這個groupBean的BeanDefinition
  4. 遍歷注解的name
  5. 通過定義的key(localMap)獲得PropertyValue屬性值
  6. 首次屬性值為空,創(chuàng)建一個PropertyValue(以localMap為key,ManagedMap為value)
  7. 將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("批量創(chuàng)建策略實例").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);
            }

        }
    }
}

到了這里,關(guān)于設(shè)計模式-策略工廠的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包