Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[sisu-users] Question about @Priority


Hello,

In general I can annotate @Named classes with @Priority and injection will take this into account properly returning the highest priority binding:

public class FirstImpl implements Service
@Named @Priority(10)
public class SecondImpl implements Service

// the following will return SecondImpl as the first candidate
locator.locate(Keys.get(Service.class)); 

@Priority however seems to be ignored when a Provider is used. For example:

public class FirstImpl implements Service
@Named @Priority(10)
public class SecondImplProvider implements Provider<Service>

// the following will return FirstImpl
locator.locate(Keys.get(Service.class));

I tried to work around the above issue specifying a custom ranking function like the following, and it seems to solve my problem.  My questions are:
  1. is the above expected, shouldn't priority be honored also if declared on Providers ?
  2. the custom ranking function below seems to solve the problem, but it performs a nested lookup using the BeanLocator. Is this acceptable or a bad practice? Are there better ways to solve this issue? I tried to look into BeanLocator, RankedBindings, RankedSequence, and the Guice SPI but I could not find an easy solution.

public class CustomRankingFunction implements RankingFunction {

    private DefaultRankingFunction delegate;
   
    @Inject
    private DefaultBeanLocator locator;

    public CustomRankingFunction(final int primaryRank) {
        delegate = new DefaultRankingFunction(primaryRank);
    }

    public CustomRankingFunction() {
        this(0);
    }

    public int maxRank() {
        return delegate.maxRank();
    }

    public <T> int rank(final Binding<T> binding) {
        if (binding instanceof ProviderKeyBinding) {
            ProviderKeyBinding pkb = (ProviderKeyBinding) binding;
            BeanEntry o1 = (BeanEntry) locator.locate(pkb.getProviderKey()).iterator().next();
            if (o1.getImplementationClass().isAnnotationPresent(Priority.class)) {
                Priority p = (Priority) o1.getImplementationClass().getAnnotation(Priority.class);
                return p.value();
            }
        }
        return delegate.rank(binding);
    }
}

--
Gian Maria Romanato
<gm.romanato (at) gmail (dot) com>

Back to the top