001: /*
002: * Copyright (C) 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package com.bm.ejb3guice.inject;
018:
019: import com.bm.ejb3guice.binder.AnnotatedBindingBuilder;
020: import com.bm.ejb3guice.binder.AnnotatedConstantBindingBuilder;
021: import com.bm.ejb3guice.binder.LinkedBindingBuilder;
022: import com.bm.ejb3guice.matcher.Matcher;
023: import com.bm.ejb3guice.spi.Message;
024:
025: import java.lang.annotation.Annotation;
026: import java.lang.reflect.Method;
027: import org.aopalliance.intercept.MethodInterceptor;
028:
029: /**
030: * Collects configuration information (primarily <i>bindings</i>) which will be
031: * used to create an {@link Injector}. Guice provides this object to your
032: * application's {@link Module} implementors so they may each contribute
033: * their own bindings and other registrations.
034: *
035: * <h3>The Guice Binding EDSL</h3>
036: *
037: * Guice uses an <i>embedded domain-specific language</i>, or EDSL, to help you
038: * create bindings simply and readably. This approach is great for overall
039: * usability, but it does come with a small cost: <b>it is difficult to
040: * learn how to use the Binding EDSL in the usual way -- by reading
041: * method-level javadocs</b>. Instead, you should consult this series of
042: * examples below. To save space, these examples omit the opening
043: * {@code binder.}, just as you will if your module extends
044: * {@link AbstractModule}.
045: *
046: * <pre>
047: * bind(ServiceImpl.class);</pre>
048: *
049: * This statement does essentially nothing; it "binds the {@code ServiceImpl}
050: * class to itself" and does not change Guice's default behavior. You may still
051: * want to use this if you prefer your {@link Module} class to serve as an
052: * explicit <i>manifest</i> for the services it provides. Also, in rare cases,
053: * Guice may be unable to validate a binding at injector creation time unless it
054: * is given explicitly.
055: *
056: * <pre>
057: * bind(Service.class).to(ServiceImpl.class);</pre>
058: *
059: * Specifies that a request for a {@code Service} instance with no binding
060: * annotations should be treated as if it were a request for a
061: * {@code ServiceImpl} instance. This <i>overrides</i> the function of any
062: * {@link ImplementedBy @ImplementedBy} or {@link ProvidedBy @ProvidedBy}
063: * annotations found on {@code Service}, since Guice will have already
064: * "moved on" to {@code ServiceImpl} before it reaches the point when it starts
065: * looking for these annotations.
066: *
067: * <pre>
068: * bind(Service.class).toProvider(ServiceProvider.class);</pre>
069: *
070: * In this example, {@code ServiceProvider} must extend or implement
071: * {@code Provider<Service>}. This binding specifies that Guice should resolve
072: * an unannotated injection request for {@code Service} by first resolving an
073: * instance of {@code ServiceProvider} in the regular way, then calling
074: * {@link Provider#get get()} on the resulting Provider instance to obtain the
075: * {@code Service} instance.
076: *
077: * <p>The {@link Provider} you use here does not have to be a "factory"; that
078: * is, a provider which always <i>creates</i> each instance it provides.
079: * However, this is generally a good practice to follow. You can then use
080: * Guice's concept of {@link Scope scopes} to guide when creation should happen
081: * -- "letting Guice work for you".
082: *
083: * <pre>
084: * bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);</pre>
085: *
086: * Like the previous example, but only applies to injection requests that use
087: * the binding annotation {@code @Red}. If your module also includes bindings
088: * for particular <i>values</i> of the {@code @Red} annotation (see below),
089: * then this binding will serve as a "catch-all" for any values of {@code @Red}
090: * that have no exact match in the bindings.
091: *
092: * <pre>
093: * bind(ServiceImpl.class).in(Singleton.class);
094: * // or, alternatively
095: * bind(ServiceImpl.class).in(Scopes.SINGLETON);</pre>
096: *
097: * Either of these statements places the {@code ServiceImpl} class into
098: * singleton scope. Guice will create only one instance of {@code ServiceImpl}
099: * and will reuse it for all injection requests of this type. Note that it is
100: * still possible to bind another instance of {@code ServiceImpl} if the second
101: * binding is qualified by an annotation as in the previous example. Guice is
102: * not overly concerned with <i>preventing</i> you from creating multiple
103: * instances of your "singletons", only with <i>enabling</i> your application to
104: * share only one instance if that's all you tell Guice you need.
105: *
106: * <p><b>Note:</b> a scope specified in this way <i>overrides</i> any scope that
107: * was specified with an annotation on the {@code ServiceImpl} class.
108: *
109: * <p>Besides {@link Singleton}/{@link Scopes#SINGLETON}, there are
110: * servlet-specific scopes available in
111: * {@code com.bm.ejb3guice.servlet.ServletScopes}, and your Modules can
112: * contribute their own custom scopes for use here as well.
113: *
114: * <pre>
115: * bind(new TypeLiteral<PaymentService<CreditCard>>() {})
116: * .to(CreditCardPaymentService.class);</pre>
117: *
118: * This admittedly odd construct is the way to bind a parameterized type. It
119: * tells Guice how to honor an injection request for an element of type
120: * {@code PaymentService<CreditCard>}. The class
121: * {@code CreditCardPaymentService} must implement the
122: * {@code PaymentService<CreditCard>} interface. Guice cannot currently bind or
123: * inject a generic type, such as {@code Set<E>}; all type parameters must be
124: * fully specified.
125: *
126: * <pre>
127: * bind(Service.class).toInstance(new ServiceImpl());
128: * // or, alternatively
129: * bind(Service.class).toInstance(SomeLegacyRegistry.getService());</pre>
130: *
131: * In this example, your module itself, <i>not Guice</i>, takes responsibility
132: * for obtaining a {@code ServiceImpl} instance, then asks Guice to always use
133: * this single instance to fulfill all {@code Service} injection requests. When
134: * the {@link Injector} is first created, it will automatically perform field
135: * and method injection for this instance, but any injectable constructor on
136: * {@code ServiceImpl} is simply ignored. Note that using this approach results
137: * in "eager loading" behavior that you can't control.
138: *
139: * <pre>
140: * bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre>
141: *
142: * Sets up a constant binding. Constant bindings are typeless in Guice; you
143: * can provide the values in a variety of types and the values can be injected
144: * in a variety of types; Guice performs the standard type conversions for you
145: * behind the scenes. Because of this "typelessness", constant injections must
146: * always be annotated.
147: *
148: * <pre>
149: * {@literal @}Color("red") Color red; // A member variable (field)
150: * . . .
151: * red = MyModule.class.getField("red").getAnnotation(Color.class);
152: * bind(Service.class).annotatedWith(red).to(RedService.class);</pre>
153: *
154: * If your binding annotation has parameters you can apply different bindings to
155: * different specific values of your annotation. Getting your hands on the
156: * right instance of the annotation is a bit of a pain -- one approach, shown
157: * above, is to apply a prototype annotation to a field in your module class, so
158: * that you can read this annotation instance and give it to Guice.
159: *
160: * <pre>
161: * bind(Service.class)
162: * .annotatedWith(Names.named("blue"))
163: * .to(BlueService.class);</pre>
164: *
165: * Differentiating by names is a common enough use case that we provided a
166: * standard annotation, {@link com.bm.ejb3guice.name.Named @Named}. Because of
167: * Guice's library support, binding by name is quite easier than in the
168: * arbitrary binding annotation case we just saw. However, remember that these
169: * names will live in a single flat namespace with all the other names used in
170: * your application.
171: *
172: * <p>The above list of examples is far from exhaustive. If you can think of
173: * how the concepts of one example might coexist with the concepts from another,
174: * you can most likely weave the two together. If the two concepts make no
175: * sense with each other, you most likely won't be able to do it. In a few
176: * cases Guice will let something bogus slip by, and will then inform you of
177: * the problems at runtime, as soon as you try to create your Injector.
178: *
179: * <p>The other methods of Binder such as {@link #bindScope},
180: * {@link #bindInterceptor}, {@link #install}, {@link #requestStaticInjection},
181: * {@link #addError} and {@link #currentStage} are not part of the Binding EDSL;
182: * you can learn how to use these in the usual way, from the method
183: * documentation.
184: *
185: * @author crazybob@google.com (Bob Lee)
186: */
187: public interface Binder {
188:
189: /**
190: * Binds a method interceptor to methods matched by class and method
191: * matchers.
192: *
193: * @param classMatcher matches classes the interceptor should apply to. For
194: * example: {@code only(Runnable.class)}.
195: * @param methodMatcher matches methods the interceptor should apply to. For
196: * example: {@code annotatedWith(Transactional.class)}.
197: * @param interceptors to bind
198: */
199: void bindInterceptor(Matcher<? super Class<?>> classMatcher,
200: Matcher<? super Method> methodMatcher,
201: MethodInterceptor... interceptors);
202:
203: /**
204: * Binds a scope to an annotation.
205: */
206: void bindScope(Class<? extends Annotation> annotationType,
207: Scope scope);
208:
209: /**
210: * See the EDSL examples at {@link Binder}.
211: */
212: <T> LinkedBindingBuilder<T> bind(Key<T> key);
213:
214: /**
215: * See the EDSL examples at {@link Binder}.
216: */
217: <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral);
218:
219: /**
220: * See the EDSL examples at {@link Binder}.
221: */
222: <T> AnnotatedBindingBuilder<T> bind(Class<T> type);
223:
224: /**
225: * See the EDSL examples at {@link Binder}.
226: */
227: AnnotatedConstantBindingBuilder bindConstant();
228:
229: /**
230: * Upon successful creation, the {@link Injector} will inject static fields
231: * and methods in the given classes.
232: *
233: * @param types for which static members will be injected
234: */
235: void requestStaticInjection(Class<?>... types);
236:
237: /**
238: * Uses the given module to configure more bindings.
239: */
240: void install(Module module);
241:
242: /**
243: * Gets the current stage.
244: */
245: Stage currentStage();
246:
247: /**
248: * Records an error message which will be presented to the user at a later
249: * time. Unlike throwing an exception, this enable us to continue
250: * configuring the Injector and discover more errors. Uses {@link
251: * String#format(String, Object[])} to insert the arguments into the
252: * message.
253: */
254: void addError(String message, Object... arguments);
255:
256: /**
257: * Records an exception, the full details of which will be logged, and the
258: * message of which will be presented to the user at a later
259: * time. If your Module calls something that you worry may fail, you should
260: * catch the exception and pass it into this.
261: */
262: void addError(Throwable t);
263:
264: /**
265: * Returns the provider used to obtain instances for the given injection key.
266: * The returned will not be valid until the {@link Injector} has been
267: * created. The provider will throw an {@code IllegalStateException} if you
268: * try to use it beforehand.
269: */
270: <T> Provider<T> getProvider(Key<T> key);
271:
272: /**
273: * Returns the provider used to obtain instances for the given injection type.
274: * The returned will not be valid until the {@link Injector} has been
275: * created. The provider will throw an {@code IllegalStateException} if you
276: * try to use it beforehand.
277: */
278: <T> Provider<T> getProvider(Class<T> type);
279: }
|