
infra.beans.factory.annotation.Autowired Maven / Gradle / Ivy
/*
* Copyright 2017 - 2024 the original author or authors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see [https://www.gnu.org/licenses/]
*/
package infra.beans.factory.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import infra.core.Ordered;
import infra.core.annotation.Order;
/**
* Marks a constructor, parameter, field, setter method, or config method as to be
* autowired by dependency injection facilities. This is an alternative to the JSR-330
* {@link jakarta.inject.Inject} annotation, adding required-vs-optional semantics.
*
* Autowired Constructors
* Only one constructor of any given bean class may declare this annotation with the
* {@link #required} attribute set to {@code true}, indicating the constructor
* to autowire when used as a bean. Furthermore, if the {@code required} attribute is
* set to {@code true}, only a single constructor may be annotated
* with {@code @Autowired}. If multiple non-required constructors declare the
* annotation, they will be considered as candidates for autowiring. The constructor
* with the greatest number of dependencies that can be satisfied by matching beans
* in the factory will be chosen. If none of the candidates can be satisfied,
* then a primary/default constructor (if present) will be used. Similarly, if a
* class declares multiple constructors but none of them is annotated with
* {@code @Autowired}, then a primary/default constructor (if present) will be used.
* If a class only declares a single constructor to begin with, it will always be used,
* even if not annotated. An annotated constructor does not have to be public.
*
*
Autowired Fields
* Fields are injected right after construction of a bean, before any config methods
* are invoked. Such a config field does not have to be public.
*
*
Autowired Methods
* Config methods may have an arbitrary name and any number of arguments; each of
* those arguments will be autowired with a matching bean in the factory.
* Bean property setter methods are effectively just a special case of such a general
* config method. Such config methods do not have to be public.
*
*
Autowired Parameters
* Although {@code @Autowired} can technically be declared on individual method
* or constructor parameters
*
*
Multiple Arguments and 'required' Semantics
* In the case of a multi-arg constructor or method, the {@link #required} attribute
* is applicable to all arguments. Individual parameters may be declared as Java-8 style
* {@link java.util.Optional} or, also as {@code @Nullable} overriding the base 'required' semantics.
*
*
Autowiring Arrays, Collections, and Maps
* In case of an array, {@link java.util.Collection}, or {@link java.util.Map}
* dependency type, the container autowiring all beans matching the declared value
* type. For such purposes, the map keys must be declared as type {@code String}
* which will be resolved to the corresponding bean names. Such a container-provided
* collection will be ordered, taking into account
* {@link Ordered Ordered} and {@link Order @Order}
* values of the target components, otherwise following their registration order
* in the container. Alternatively, a single matching target bean may also be a
* generally typed {@code Collection} or {@code Map} itself, getting injected as such.
*
* @author TODAY 2018-?-? ?:?
* @see Value
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD,
ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
*
Defaults to {@code true}.
*/
boolean required() default true;
}