1 16 17 package com.google.inject; 18 19 import com.google.inject.util.StackTraceElements; 20 import java.lang.reflect.Constructor ; 21 import java.lang.reflect.InvocationTargetException ; 22 23 28 class ConstructorInjector<T> { 29 30 final Class <T> implementation; 31 final InjectorImpl.SingleMemberInjector[] memberInjectors; 32 final InjectorImpl.SingleParameterInjector<?>[] parameterInjectors; 33 final ConstructionProxy<T> constructionProxy; 34 35 ConstructorInjector(InjectorImpl injector, Class <T> implementation) { 36 this.implementation = implementation; 37 Constructor <T> constructor = findConstructorIn(injector, implementation); 38 parameterInjectors = createParameterInjector(injector, constructor); 39 memberInjectors = injector.injectors.get(implementation) 40 .toArray(new InjectorImpl.SingleMemberInjector[0]); 41 constructionProxy = injector.constructionProxyFactory.get(constructor); 42 } 43 44 47 private ConstructorInjector() { 48 implementation = null; 49 memberInjectors = null; 50 parameterInjectors = null; 51 constructionProxy = null; 52 } 53 54 InjectorImpl.SingleParameterInjector<?>[] createParameterInjector( 55 InjectorImpl injector, Constructor <T> constructor) { 56 try { 57 return constructor.getParameterTypes().length == 0 58 ? null : injector.getParametersInjectors( 60 constructor, 61 constructor.getParameterAnnotations(), 62 constructor.getGenericParameterTypes() 63 ); 64 } 65 catch (InjectorImpl.MissingDependencyException e) { 66 e.handle(injector.errorHandler); 67 return null; 68 } 69 } 70 71 private Constructor <T> findConstructorIn(InjectorImpl injector, 72 Class <T> implementation) { 73 Constructor <T> found = null; 74 @SuppressWarnings ("unchecked") 75 Constructor <T>[] constructors 76 = (Constructor <T>[]) implementation.getDeclaredConstructors(); 77 for (Constructor <T> constructor : constructors) { 78 Inject inject = constructor.getAnnotation(Inject.class); 79 if (inject != null) { 80 if (inject.optional()) { 81 injector.errorHandler.handle( 82 StackTraceElements.forMember(constructor), 83 ErrorMessages.OPTIONAL_CONSTRUCTOR); 84 } 85 86 if (found != null) { 87 injector.errorHandler.handle( 88 StackTraceElements.forMember(found), 89 ErrorMessages.TOO_MANY_CONSTRUCTORS); 90 return InjectorImpl.invalidConstructor(); 91 } 92 found = constructor; 93 } 94 } 95 if (found != null) { 96 return found; 97 } 98 99 try { 102 return implementation.getDeclaredConstructor(); 103 } 104 catch (NoSuchMethodException e) { 105 injector.errorHandler.handle( 106 StackTraceElements.forMember( 107 implementation.getDeclaredConstructors()[0]), 108 ErrorMessages.MISSING_CONSTRUCTOR, 109 implementation); 110 return InjectorImpl.invalidConstructor(); 111 } 112 } 113 114 118 Object construct(InternalContext context, Class <?> expectedType) { 119 ConstructionContext<T> constructionContext 120 = context.getConstructionContext(this); 121 122 if (constructionContext.isConstructing()) { 124 return constructionContext.createProxy(expectedType); 127 } 128 129 T t = constructionContext.getCurrentReference(); 132 if (t != null) { 133 return t; 134 } 135 136 try { 137 constructionContext.startConstruction(); 139 try { 140 Object [] parameters 141 = InjectorImpl.getParameters(context, parameterInjectors); 142 t = constructionProxy.newInstance(parameters); 143 constructionContext.setProxyDelegates(t); 144 } 145 finally { 146 constructionContext.finishConstruction(); 147 } 148 149 constructionContext.setCurrentReference(t); 152 153 for (InjectorImpl.SingleMemberInjector injector : memberInjectors) { 155 injector.inject(context, t); 156 } 157 158 return t; 159 } 160 catch (InvocationTargetException e) { 161 throw new RuntimeException (e); 162 } 163 finally { 164 constructionContext.removeCurrentReference(); 165 } 166 } 167 168 172 static <T> ConstructorInjector<T> invalidConstructor() { 173 return new ConstructorInjector<T>() { 174 Object construct(InternalContext context, Class <?> expectedType) { 175 throw new UnsupportedOperationException (); 176 } 177 public T get() { 178 throw new UnsupportedOperationException (); 179 } 180 }; 181 } 182 } 183 | Popular Tags |