All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wantedtech.common.xpresso.helpers.inject.Inject Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2009 The JSR-330 Expert Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wantedtech.common.xpresso.helpers.inject;

import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.Documented;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;

/**
 * Identifies injectable constructors, methods, and fields. May apply to static
 * as well as instance members. An injectable member may have any access
 * modifier (private, package-private, protected, public). Constructors are
 * injected first, followed by fields, and then methods. Fields and methods
 * in superclasses are injected before those in subclasses. Ordering of
 * injection among fields and among methods in the same class is not specified.
 *
 * 

Injectable constructors are annotated with {@code @Inject} and accept * zero or more dependencies as arguments. {@code @Inject} can apply to at most * one constructor per class. * *

@Inject * ConstructorModifiersopt * SimpleTypeName(FormalParameterListopt) * Throwsopt * ConstructorBody
* *

{@code @Inject} is optional for public, no-argument constructors when no * other constructors are present. This enables injectors to invoke default * constructors. * *

* {@literal @}Injectopt * Annotationsopt * public * SimpleTypeName() * Throwsopt * ConstructorBody
* *

Injectable fields: *

    *
  • are annotated with {@code @Inject}. *
  • are not final. *
  • may have any otherwise valid name.
* *

@Inject * FieldModifiersopt * Type * VariableDeclarators;
* *

Injectable methods: *

    *
  • are annotated with {@code @Inject}.
  • *
  • are not abstract.
  • *
  • do not declare type parameters of their own.
  • *
  • may return a result
  • *
  • may have any otherwise valid name.
  • *
  • accept zero or more dependencies as arguments.
* *

@Inject * MethodModifiersopt * ResultType * Identifier(FormalParameterListopt) * Throwsopt * MethodBody
* *

The injector ignores the result of an injected method, but * non-{@code void} return types are allowed to support use of the method in * other contexts (builder-style method chaining, for example). * *

Examples: * *

 *   public class Car {
 *     // Injectable constructor
 *     @Inject public Car(Engine engine) { ... }
 *
 *     // Injectable field
 *     @Inject private Provider<Seat> seatProvider;
 *
 *     // Injectable package-private method
 *     @Inject void install(Windshield windshield, Trunk trunk) { ... }
 *   }
* *

A method annotated with {@code @Inject} that overrides another method * annotated with {@code @Inject} will only be injected once per injection * request per instance. A method with no {@code @Inject} annotation * that overrides a method annotated with {@code @Inject} will not be * injected. * *

Injection of members annotated with {@code @Inject} is required. While an * injectable member may use any accessibility modifier (including * private), platform or injector limitations (like security * restrictions or lack of reflection support) might preclude injection * of non-public members. * *

Qualifiers

* *

A {@linkplain Qualifier qualifier} may annotate an injectable field * or parameter and, combined with the type, identify the implementation to * inject. Qualifiers are optional, and when used with {@code @Inject} in * injector-independent classes, no more than one qualifier should annotate a * single field or parameter. The qualifiers are bold in the following example: * *

 *   public class Car {
 *     @Inject private @Leather Provider<Seat> seatProvider;
 *
 *     @Inject void install(@Tinted Windshield windshield,
 *         @Big Trunk trunk) { ... }
 *   }
* *

If one injectable method overrides another, the overriding method's * parameters do not automatically inherit qualifiers from the overridden * method's parameters. * *

Injectable Values

* *

For a given type T and optional qualifier, an injector must be able to * inject a user-specified class that: * *

    *
  1. is assignment compatible with T and
  2. *
  3. has an injectable constructor.
  4. *
* *

For example, the user might use external configuration to pick an * implementation of T. Beyond that, which values are injected depend upon the * injector implementation and its configuration. * *

Circular Dependencies

* *

Detecting and resolving circular dependencies is left as an exercise for * the injector implementation. Circular dependencies between two constructors * is an obvious problem, but you can also have a circular dependency between * injectable fields or methods: * *

 *   class A {
 *     @Inject B b;
 *   }
 *   class B {
 *     @Inject A a;
 *   }
* *

When constructing an instance of {@code A}, a naive injector * implementation might go into an infinite loop constructing an instance of * {@code B} to set on {@code A}, a second instance of {@code A} to set on * {@code B}, a second instance of {@code B} to set on the second instance of * {@code A}, and so on. * *

A conservative injector might detect the circular dependency at build * time and generate an error, at which point the programmer could break the * circular dependency by injecting {@link Provider Provider<A>} or {@code * Provider} instead of {@code A} or {@code B} respectively. Calling {@link * Provider#get() get()} on the provider directly from the constructor or * method it was injected into defeats the provider's ability to break up * circular dependencies. In the case of method or field injection, scoping * one of the dependencies (using {@linkplain Singleton singleton scope}, for * example) may also enable a valid circular relationship. * * @see javax.inject.Qualifier @Qualifier * @see javax.inject.Provider */ @Target({ METHOD, CONSTRUCTOR, FIELD }) @Retention(RUNTIME) @Documented public @interface Inject {}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy