• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.base.Preconditions.checkState;
21 
22 import com.google.inject.binder.AnnotatedBindingBuilder;
23 import com.google.inject.binder.AnnotatedConstantBindingBuilder;
24 import com.google.inject.binder.LinkedBindingBuilder;
25 import com.google.inject.matcher.Matcher;
26 import com.google.inject.spi.Message;
27 import com.google.inject.spi.ProvisionListener;
28 import com.google.inject.spi.TypeConverter;
29 import com.google.inject.spi.TypeListener;
30 import java.lang.annotation.Annotation;
31 import java.lang.reflect.Method;
32 
33 /**
34  * A support class for {@link Module}s which reduces repetition and results in a more readable
35  * configuration. Simply extend this class, implement {@link #configure()}, and call the inherited
36  * methods which mirror those found in {@link Binder}. For example:
37  *
38  * <pre>
39  * public class MyModule extends AbstractModule {
40  *   protected void configure() {
41  *     bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
42  *     bind(CreditCardPaymentService.class);
43  *     bind(PaymentService.class).to(CreditCardPaymentService.class);
44  *     bindConstant().annotatedWith(Names.named("port")).to(8080);
45  *   }
46  * }
47  * </pre>
48  *
49  * @author crazybob@google.com (Bob Lee)
50  */
51 public abstract class AbstractModule implements Module {
52 
53   Binder binder;
54 
55   @Override
configure(Binder builder)56   public final synchronized void configure(Binder builder) {
57     checkState(this.binder == null, "Re-entry is not allowed.");
58 
59     this.binder = checkNotNull(builder, "builder");
60     try {
61       configure();
62     } finally {
63       this.binder = null;
64     }
65   }
66 
67   /** Configures a {@link Binder} via the exposed methods. */
configure()68   protected void configure() {}
69 
70   /** Gets direct access to the underlying {@code Binder}. */
binder()71   protected Binder binder() {
72     checkState(binder != null, "The binder can only be used inside configure()");
73     return binder;
74   }
75 
76   /** @see Binder#bindScope(Class, Scope) */
bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope)77   protected void bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope) {
78     binder().bindScope(scopeAnnotation, scope);
79   }
80 
81   /** @see Binder#bind(Key) */
bind(Key<T> key)82   protected <T> LinkedBindingBuilder<T> bind(Key<T> key) {
83     return binder().bind(key);
84   }
85 
86   /** @see Binder#bind(TypeLiteral) */
bind(TypeLiteral<T> typeLiteral)87   protected <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
88     return binder().bind(typeLiteral);
89   }
90 
91   /** @see Binder#bind(Class) */
bind(Class<T> clazz)92   protected <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
93     return binder().bind(clazz);
94   }
95 
96   /** @see Binder#bindConstant() */
bindConstant()97   protected AnnotatedConstantBindingBuilder bindConstant() {
98     return binder().bindConstant();
99   }
100 
101   /** @see Binder#install(Module) */
install(Module module)102   protected void install(Module module) {
103     binder().install(module);
104   }
105 
106   /** @see Binder#addError(String, Object[]) */
addError(String message, Object... arguments)107   protected void addError(String message, Object... arguments) {
108     binder().addError(message, arguments);
109   }
110 
111   /** @see Binder#addError(Throwable) */
addError(Throwable t)112   protected void addError(Throwable t) {
113     binder().addError(t);
114   }
115 
116   /**
117    * @see Binder#addError(Message)
118    * @since 2.0
119    */
addError(Message message)120   protected void addError(Message message) {
121     binder().addError(message);
122   }
123 
124   /**
125    * @see Binder#requestInjection(Object)
126    * @since 2.0
127    */
requestInjection(Object instance)128   protected void requestInjection(Object instance) {
129     binder().requestInjection(instance);
130   }
131 
132   /** @see Binder#requestStaticInjection(Class[]) */
requestStaticInjection(Class<?>.... types)133   protected void requestStaticInjection(Class<?>... types) {
134     binder().requestStaticInjection(types);
135   }
136 
137   /*if[AOP]*/
138   /**
139    * @see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
140    *     com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
141    */
bindInterceptor( Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher, org.aopalliance.intercept.MethodInterceptor... interceptors)142   protected void bindInterceptor(
143       Matcher<? super Class<?>> classMatcher,
144       Matcher<? super Method> methodMatcher,
145       org.aopalliance.intercept.MethodInterceptor... interceptors) {
146     binder().bindInterceptor(classMatcher, methodMatcher, interceptors);
147   }
148   /*end[AOP]*/
149 
150   /**
151    * Adds a dependency from this module to {@code key}. When the injector is created, Guice will
152    * report an error if {@code key} cannot be injected. Note that this requirement may be satisfied
153    * by implicit binding, such as a public no-arguments constructor.
154    *
155    * @since 2.0
156    */
requireBinding(Key<?> key)157   protected void requireBinding(Key<?> key) {
158     binder().getProvider(key);
159   }
160 
161   /**
162    * Adds a dependency from this module to {@code type}. When the injector is created, Guice will
163    * report an error if {@code type} cannot be injected. Note that this requirement may be satisfied
164    * by implicit binding, such as a public no-arguments constructor.
165    *
166    * @since 2.0
167    */
requireBinding(Class<?> type)168   protected void requireBinding(Class<?> type) {
169     binder().getProvider(type);
170   }
171 
172   /**
173    * @see Binder#getProvider(Key)
174    * @since 2.0
175    */
getProvider(Key<T> key)176   protected <T> Provider<T> getProvider(Key<T> key) {
177     return binder().getProvider(key);
178   }
179 
180   /**
181    * @see Binder#getProvider(Class)
182    * @since 2.0
183    */
getProvider(Class<T> type)184   protected <T> Provider<T> getProvider(Class<T> type) {
185     return binder().getProvider(type);
186   }
187 
188   /**
189    * @see Binder#convertToTypes
190    * @since 2.0
191    */
convertToTypes( Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter)192   protected void convertToTypes(
193       Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
194     binder().convertToTypes(typeMatcher, converter);
195   }
196 
197   /**
198    * @see Binder#currentStage()
199    * @since 2.0
200    */
currentStage()201   protected Stage currentStage() {
202     return binder().currentStage();
203   }
204 
205   /**
206    * @see Binder#getMembersInjector(Class)
207    * @since 2.0
208    */
getMembersInjector(Class<T> type)209   protected <T> MembersInjector<T> getMembersInjector(Class<T> type) {
210     return binder().getMembersInjector(type);
211   }
212 
213   /**
214    * @see Binder#getMembersInjector(TypeLiteral)
215    * @since 2.0
216    */
getMembersInjector(TypeLiteral<T> type)217   protected <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> type) {
218     return binder().getMembersInjector(type);
219   }
220 
221   /**
222    * @see Binder#bindListener(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeListener)
223    * @since 2.0
224    */
bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener)225   protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
226     binder().bindListener(typeMatcher, listener);
227   }
228 
229   /**
230    * @see Binder#bindListener(Matcher, ProvisionListener...)
231    * @since 4.0
232    */
bindListener( Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listener)233   protected void bindListener(
234       Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listener) {
235     binder().bindListener(bindingMatcher, listener);
236   }
237 }
238