📄 containerimpl.java
字号:
new ReferenceCache<Class<?>, ConstructorInjector>() { @SuppressWarnings("unchecked") protected ConstructorInjector<?> create(Class<?> implementation) { return new ConstructorInjector(ContainerImpl.this, implementation); } }; static class ConstructorInjector<T> { final Class<T> implementation; final List<Injector> injectors; final Constructor<T> constructor; final ParameterInjector<?>[] parameterInjectors; ConstructorInjector(ContainerImpl container, Class<T> implementation) { this.implementation = implementation; constructor = findConstructorIn(implementation); constructor.setAccessible(true); try { Inject inject = constructor.getAnnotation(Inject.class); parameterInjectors = inject == null ? null // default constructor. : container.getParametersInjectors( constructor, constructor.getParameterAnnotations(), constructor.getParameterTypes(), inject.value() ); } catch (MissingDependencyException e) { throw new DependencyException(e); } injectors = container.injectors.get(implementation); } @SuppressWarnings("unchecked") private Constructor<T> findConstructorIn(Class<T> implementation) { Constructor<T> found = null; Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation .getDeclaredConstructors(); for(Constructor<T> constructor : declaredConstructors) { if (constructor.getAnnotation(Inject.class) != null) { if (found != null) { throw new DependencyException("More than one constructor annotated" + " with @Inject found in " + implementation + "."); } found = constructor; } } if (found != null) { return found; } // If no annotated constructor is found, look for a no-arg constructor // instead. try { return implementation.getDeclaredConstructor(); } catch (NoSuchMethodException e) { throw new DependencyException("Could not find a suitable constructor" + " in " + implementation.getName() + "."); } } /** * Construct an instance. Returns {@code Object} instead of {@code T} * because it may return a proxy. */ Object construct(InternalContext context, Class<? super T> expectedType) { ConstructionContext<T> constructionContext = context.getConstructionContext(this); // We have a circular reference between constructors. Return a proxy. if (constructionContext.isConstructing()) { // TODO (crazybob): if we can't proxy this object, can we proxy the // other object? return constructionContext.createProxy(expectedType); } // If we're re-entering this factory while injecting fields or methods, // return the same instance. This prevents infinite loops. T t = constructionContext.getCurrentReference(); if (t != null) { return t; } try { // First time through... constructionContext.startConstruction(); try { Object[] parameters = getParameters(constructor, context, parameterInjectors); t = constructor.newInstance(parameters); constructionContext.setProxyDelegates(t); } finally { constructionContext.finishConstruction(); } // Store reference. If an injector re-enters this factory, they'll // get the same reference. constructionContext.setCurrentReference(t); // Inject fields and methods. for (Injector injector : injectors) { injector.inject(context, t); } return t; } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } finally { constructionContext.removeCurrentReference(); } } } static class ParameterInjector<T> { final ExternalContext<T> externalContext; final InternalFactory<? extends T> factory; public ParameterInjector(ExternalContext<T> externalContext, InternalFactory<? extends T> factory) { this.externalContext = externalContext; this.factory = factory; } T inject(Member member, InternalContext context) { ExternalContext<?> previous = context.getExternalContext(); context.setExternalContext(externalContext); try { return factory.create(context); } finally { context.setExternalContext(previous); } } } private static Object[] getParameters(Member member, InternalContext context, ParameterInjector[] parameterInjectors) { if (parameterInjectors == null) { return null; } Object[] parameters = new Object[parameterInjectors.length]; for (int i = 0; i < parameters.length; i++) { parameters[i] = parameterInjectors[i].inject(member, context); } return parameters; } void inject(Object o, InternalContext context) { List<Injector> injectors = this.injectors.get(o.getClass()); for (Injector injector : injectors) { injector.inject(context, o); } } <T> T inject(Class<T> implementation, InternalContext context) { try { ConstructorInjector<T> constructor = getConstructor(implementation); return implementation.cast( constructor.construct(context, implementation)); } catch (Exception e) { throw new RuntimeException(e); } } @SuppressWarnings("unchecked") <T> T getInstance(Class<T> type, String name, InternalContext context) { ExternalContext<?> previous = context.getExternalContext(); Key<T> key = Key.newInstance(type, name); context.setExternalContext(ExternalContext.newInstance(null, key, this)); try { InternalFactory o = getFactory(key); if (o != null) { return getFactory(key).create(context); } else { return null; } } finally { context.setExternalContext(previous); } } <T> T getInstance(Class<T> type, InternalContext context) { return getInstance(type, DEFAULT_NAME, context); } public void inject(final Object o) { callInContext(new ContextualCallable<Void>() { public Void call(InternalContext context) { inject(o, context); return null; } }); } public <T> T inject(final Class<T> implementation) { return callInContext(new ContextualCallable<T>() { public T call(InternalContext context) { return inject(implementation, context); } }); } public <T> T getInstance(final Class<T> type, final String name) { return callInContext(new ContextualCallable<T>() { public T call(InternalContext context) { return getInstance(type, name, context); } }); } public <T> T getInstance(final Class<T> type) { return callInContext(new ContextualCallable<T>() { public T call(InternalContext context) { return getInstance(type, context); } }); } public Set<String> getInstanceNames(final Class<?> type) { return factoryNamesByType.get(type); } ThreadLocal<Object[]> localContext = new ThreadLocal<Object[]>() { protected InternalContext[] initialValue() { return new InternalContext[1]; } }; /** * Looks up thread local context. Creates (and removes) a new context if * necessary. */ <T> T callInContext(ContextualCallable<T> callable) { InternalContext[] reference = (InternalContext[]) localContext.get(); if (reference[0] == null) { reference[0] = new InternalContext(this); try { return callable.call(reference[0]); } finally { // Only remove the context if this call created it. reference[0] = null; } } else { // Someone else will clean up this context. return callable.call(reference[0]); } } interface ContextualCallable<T> { T call(InternalContext context); } /** * Gets a constructor function for a given implementation class. */ @SuppressWarnings("unchecked") <T> ConstructorInjector<T> getConstructor(Class<T> implementation) { return constructors.get(implementation); } final ThreadLocal<Object> localScopeStrategy = new ThreadLocal<Object>(); public void setScopeStrategy(Scope.Strategy scopeStrategy) { this.localScopeStrategy.set(scopeStrategy); } public void removeScopeStrategy() { this.localScopeStrategy.remove(); } /** * Injects a field or method in a given object. */ interface Injector extends Serializable { void inject(InternalContext context, Object o); } static class MissingDependencyException extends Exception { MissingDependencyException(String message) { super(message); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -