开发者

Hidden Features of Google Guice [closed]

开发者 https://www.devze.com 2022-12-28 11:14 出处:网络
开发者_Go百科 As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references,or expertise, but this question will likely soli
开发者_Go百科 As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. Closed 10 years ago.

Google Guice provides some great dependency injection features.

I came across the @Nullable feature recently which allows you to mark constructor arguments as optional (permitting null) since Guice does not permit these by default:

e.g.

public Person(String firstName, String lastName, @Nullable Phone phone) {
    this.firstName = checkNotNull(firstName, "firstName");
    this.lastName = checkNotNull(lastName, "lastName");
    this.phone = phone;
}

https://github.com/google/guice/wiki/UseNullable

What are the other useful features of Guice (particularly the less obvious ones) that people use?


None of 'em are intended to be hidden, but these are my favorite 'bonus features' in Guice:

  • Guice can inject a TypeLiteral<T>, effectively defeating erasure.
  • TypeLiteral can do generic type resolution: this tells you that get() on a List<String> returns an Iterator<String>.
  • Types is a factory for implementations of Java's generic type interfaces.
  • Grapher visualizes injectors. If your custom provider implements HasDependencies, it can augment this graph.
  • Modules.override() is incredibly handy in a pinch.
  • Short syntax for defining parameterized keys: new Key<List<String>>() {}.
  • Binder.skipSources() lets you to write extensions whose error messages track line numbers properly.
  • The SPI. Elements.getElements() breaks a module into atoms and Elements.getModule() puts them back together.
  • If you implement equals() and hashCode() in a Module, you can install that module multiple times without problem.


I like how totally open the Scope interface is: basically, it's just a transformation from Provider to Provider. (Okay, from Key and Provider to Provider)

Want some things to be basically Singleton, but re-read from the database every half hour? It's easy to make a scope for that. Want to run some requests in the background, and have a scope that means "all background requests started from the same HTTP request?" It's relatively easy to write that Scope too.

Want to scope some Key on your server during tests so that it uses a separate instance for each test that you're running from a client? (With the test passing the test id in a Cookie or extra HTTP parameter) That's harder to do, but it's perfectly possible and so someone's already written that for you.

Yes, excessive abuse of Scope will cause Jesse to start hunting around for the stakes and garlic cloves, but its amazing flexibility can be really useful.


One great feature of Guice is how easy it makes implementing method interceptors in any Module, using:

public void bindInterceptor(
    Matcher<? super Class<?>> classMatcher,
    Matcher<? super Method> methodMatcher,
    MethodInterceptor... interceptors);

Now, any method matching methodMatcher within a class matching classMatcher in that Module's scope is intercepted by interceptors.

For example:

bindInterceptor(
    Matchers.any(),
    Matchers.annotatedWith(Retryable.class),
    new RetryableInterceptor());

Now, we can simply annotate any method with @Retryable and our RetryableInterceptor can retry it if it fails.

0

精彩评论

暂无评论...
验证码 换一张
取 消