栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring实现在多个Primary中选择其中一个注入,Spring自动注入属性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring实现在多个Primary中选择其中一个注入,Spring自动注入属性

			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {//bean初始化后的操作
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}

 上面是spring在将给定的属性给对象时调用InstantiationAwareBeanPostProcessor的postProcessProperties(AutowiredAnnotationBeanPostProcessor实现了自动注入属性)

开始实现多个primary选择其中的一个

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@documented
public @interface OrderedPrimary {
    int order() default 0;
}
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.util.*;

@Component
public class DeterminedPrimaryPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryPostProcessor {
    private ConfigurableListableBeanFactory beanFactory;
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        ReflectionUtils.doWithFields(bean.getClass(),field -> {
            MergedAnnotations mergedAnnotations = MergedAnnotations.from(field);
            MergedAnnotation autowiredMergedAnnotation = mergedAnnotations.get(Autowired.class);
            if(autowiredMergedAnnotation.isPresent()){
                determineClass(field.getType());
            }
        });
        return pvs;
    }

    private void determineClass(Class cls){
        Map> orderPrimaryDefinition = new HashMap<>();
        List primaryBeanDefinition = new ArrayList<>();
        String[] beanNames = beanFactory.getBeanNamesForType(cls);
        for(String beanName:beanNames){
            BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
            bd.setPrimary(false);
            if(bd!=null){
               Class targetClass = bd.getResolvableType().getRawClass();
               MergedAnnotations mergedAnnotations = MergedAnnotations.from(targetClass);
               if(mergedAnnotations.get(OrderedPrimary.class).isPresent()){
                   orderPrimaryDefinition.put(bd,mergedAnnotations.get(OrderedPrimary.class));
               }else if(mergedAnnotations.get(Primary.class).isPresent()){
                   primaryBeanDefinition.add(bd);
               }
            }
        }

        if(orderPrimaryDefinition.isEmpty()){
            if(!primaryBeanDefinition.isEmpty()){
                setBeanDefinitionsPrimary(primaryBeanDefinition,true);
            }
        }else{
            BeanDefinition bd = findMaxOrder(orderPrimaryDefinition);
            bd.setPrimary(true);
        }
    }
    private BeanDefinition findMaxOrder(Map> orderPrimaryDefinition){
        Set>> entrySet = orderPrimaryDefinition.entrySet();
        Iterator>> iterator = entrySet.iterator();
        BeanDefinition bd = null;
        int max = Integer.MIN_VALUE;
        while(iterator.hasNext()){
            Map.Entry> entry = iterator.next();
            MergedAnnotation ma = entry.getValue();
            int order = ma.getInt("order");
            if(order>max){
                bd = entry.getKey();
                max = order;
            }
        }
        return bd;
    }
    private void setBeanDefinitionsPrimary(List bds,boolean flag){
        bds.forEach(bd->{
            bd.setPrimary(flag);
        });
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

上面这串代码实现的是选择其中最大的order作为注入参数,测一下

@Component
public class Person {
    @Autowired
    public Animal pet;
}

public interface Animal {

}

@Component
@Primary
@OrderedPrimary(order = 3)
public class Dog implements Animal{

}

@Component
@Primary
@OrderedPrimary(order = 2)
public class Duck implements Animal {
}

输出结果

 还可以自己实现多个构造选择其中一个

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/458901.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号