有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Spring中直接获得最高顺序的bean而不使用注入列表?

有3个类UVW实现接口A,并由具有不同顺序值的Spring的@Order注释进行注释

我现在通过注入List<A>然后在List<A>中搜索第一个元素来获得最高阶bean

有没有更直接的方法可以在不注入整个A集合的情况下获得最高优先级的bean


共 (2) 个答案

  1. # 1 楼答案

    据我所知,在春季没有任何方法可以直接获得最高顺序的bean。因此,你的选择是

    • 遍历OrderBean并获得最高的一个—您已经做了什么
    • 创建自己的注释,例如@HighestOrdered,并对自己的bean自动连接后处理器进行编码,以仅获取最高顺序的注释(自定义后处理器here的示例)

    还有其他一些选择

    • 使用@Primary来表示您喜欢使用的bean
    • 对它使用@限定符

    但这两个问题都与你的要求不完全相同,而且都有一些缺点

    如果你严格地想做你在问题中提出的事情,我会做你已经在做的事情,然后重复它们,选择最高的顺序

  2. # 2 楼答案

    考虑javax。注释。优先事项 看来对你的情况有帮助

    @Service
    @Priority(Ordered.HIGHEST_PRECEDENCE + 1)
    class U implements A {}
    
    @Service
    @Priority(Ordered.HIGHEST_PRECEDENCE + 2)
    class V implements A {}
    
    @Service
    @Priority(Ordered.HIGHEST_PRECEDENCE + 3)
    class W implements A {}
    
    interface A {}
    
    @Service
    public class Client {
        @Autowired
        private A a;
    
        @PostConstruct
        public void init() {
            System.out.println("             " + a.getClass().getSimpleName());
        }
    }
    

    客户端。“a”将分配“U”的实例

    DefaultListableBeanFactory

        /**
         * Determine the autowire candidate in the given set of beans.
         * <p>Looks for {@code @Primary} and {@code @Priority} (in that order).
         * @param candidates a Map of candidate names and candidate instances
         * that match the required type, as returned by {@link #findAutowireCandidates}
         * @param descriptor the target dependency to match against
         * @return the name of the autowire candidate, or {@code null} if none found
         */
        protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
        ...
            String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
        ...
        }
    
        /**
         * Determine the candidate with the highest priority in the given set of beans.
         * <p>Based on {@code @javax.annotation.Priority}. As defined by the related
         * {@link org.springframework.core.Ordered} interface, the lowest value has
         * the highest priority.
         * @param candidates a Map of candidate names and candidate instances
         * (or candidate classes if not created yet) that match the required type
         * @param requiredType the target dependency type to match against
         * @return the name of the candidate with the highest priority,
         * or {@code null} if none found
         * @see #getPriority(Object)
         */
        protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
            String highestPriorityBeanName = null;
            Integer highestPriority = null;
            for (Map.Entry<String, Object> entry : candidates.entrySet()) {
                String candidateBeanName = entry.getKey();
                Object beanInstance = entry.getValue();
                Integer candidatePriority = getPriority(beanInstance);
                if (candidatePriority != null) {
                    if (highestPriorityBeanName != null) {
                        if (candidatePriority.equals(highestPriority)) {
                            throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
                                    "Multiple beans found with the same priority ('" + highestPriority +
                                    "') among candidates: " + candidates.keySet());
                        }
                        else if (candidatePriority < highestPriority) {
                            highestPriorityBeanName = candidateBeanName;
                            highestPriority = candidatePriority;
                        }
                    }
                    else {
                        highestPriorityBeanName = candidateBeanName;
                        highestPriority = candidatePriority;
                    }
                }
            }
            return highestPriorityBeanName;
        }