Anotações do núcleo da mola

Anotações do núcleo da mola

1. Visão geral

Podemos aproveitar os recursos do mecanismo Spring DI usando as anotações nos pacotesorg.springframework.beans.factory.annotation andorg.springframework.context.annotation.

Frequentemente chamamos isso de “anotações do Spring core” e iremos analisá-las neste tutorial.

2.1. @Autowired

Podemos usar@Autowired amark a dependency which Spring is going to resolve and inject. Podemos usar esta anotação com um construtor, setter ou injeção de campo.

Injeção de construtor:

class Car {
    Engine engine;

    @Autowired
    Car(Engine engine) {
        this.engine = engine;
    }
}

Injeção de incubadora:

class Car {
    Engine engine;

    @Autowired
    void setEngine(Engine engine) {
        this.engine = engine;
    }
}

Injeção em campo:

class Car {
    @Autowired
    Engine engine;
}

@Autowired tem um argumentoboolean chamadorequired com um valor padrão detrue. Ele ajusta o comportamento do Spring quando não encontra um bean adequado para conectar. Quandotrue, uma exceção é lançada, caso contrário, nada é conectado.

Observe que, se usarmos injeção de construtor, todos os argumentos do construtor serão obrigatórios.

A partir da versão 4.3, não precisamos anotar construtores com@Autowired explicitamente, a menos que declaremos pelo menos dois construtores.

Para obter mais detalhes, visite nossos artigos sobre@Autowiredeconstructor injection.

2.2. @Bean

@Bean marca um método de fábrica que instancia um bean Spring:

@Bean
Engine engine() {
    return new Engine();
}

Spring calls these methods quando uma nova instância do tipo de retorno é necessária.

O bean resultante tem o mesmo nome que o método de fábrica. Se quisermos nomeá-lo de forma diferente, podemos fazer isso com os argumentosname ouvalue desta anotação (o argumentovalue é um apelido para o argumentoname) :

@Bean("engine")
Engine getEngine() {
    return new Engine();
}

Observe que todos os métodos anotados com@Bean devem estar nas classes@Configuration.

2.3. @Qualifier

Usamos@Qualifier junto com@Autowired paraprovide the bean id or bean name que queremos usar em situações ambíguas.

Por exemplo, os dois beans a seguir implementam a mesma interface:

class Bike implements Vehicle {}

class Car implements Vehicle {}

Se o Spring precisar injetar um beanVehicle, ele terminará com várias definições correspondentes. Nesses casos, podemos fornecer o nome de um bean explicitamente usando a anotação@Qualifier.

Usando injeção de construtor:

@Autowired
Biker(@Qualifier("bike") Vehicle vehicle) {
    this.vehicle = vehicle;
}

Usando injeção setter:

@Autowired
void setVehicle(@Qualifier("bike") Vehicle vehicle) {
    this.vehicle = vehicle;
}

Alternativamente:

@Autowired
@Qualifier("bike")
void setVehicle(Vehicle vehicle) {
    this.vehicle = vehicle;
}

Usando injeção de campo:

@Autowired
@Qualifier("bike")
Vehicle vehicle;

Para uma descrição mais detalhada, leiathis article.

2.4. @Required

@Required em métodos setter para marcar dependências que desejamos preencher por meio de XML:

@Required
void setColor(String color) {
    this.color = color;
}

    

Caso contrário,BeanInitializationException será lançado.

2.5. @Value

Podemos usar@Value para injetar valores de propriedade nos beans. É compatível com construtor, setter e injeção de campo.

Injeção de construtor:

Engine(@Value("8") int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

Injeção de incubadora:

@Autowired
void setCylinderCount(@Value("8") int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

Alternativamente:

@Value("8")
void setCylinderCount(int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

Injeção em campo:

@Value("8")
int cylinderCount;

Claro, injetar valores estáticos não é útil. Portanto, podemos usarplaceholder strings em@Value para conectar valoresdefined in external sources, por exemplo, em arquivos.properties ou.yaml.

Vamos supor o seguinte arquivo.properties:

engine.fuelType=petrol

Podemos injetar o valor deengine.fuelType com o seguinte:

@Value("${engine.fuelType}")
String fuelType;

Podemos usar@Value mesmo com SpEL. Exemplos mais avançados podem ser encontrados em nossoarticle about @Value.

2.6. @DependsOn

Podemos usar essa anotação para fazer Springinitialize other beans before the annotated one. Geralmente, esse comportamento é automático, com base nas dependências explícitas entre os beans.

Precisamos apenas dessa anotaçãowhen the dependencies are implicit, por exemplo, carregamento do driver JDBC ou inicialização de variável estática.

Podemos usar@DependsOn na classe dependente especificando os nomes dos beans de dependência. O argumentovalue da anotação precisa de uma matriz contendo os nomes do bean de dependência:

@DependsOn("engine")
class Car implements Vehicle {}

Alternativamente, se definirmos um bean com a anotação@Bean, o método de fábrica deve ser anotado com@DependsOn:

@Bean
@DependsOn("fuel")
Engine engine() {
    return new Engine();
}

2.7. @Lazy

Usamos@Lazy quando queremos inicializar nosso bean preguiçosamente. Por padrão, o Spring cria todos os beans singleton ansiosamente na inicialização / inicialização do contexto do aplicativo.

Porém, há casos em quewe need to create a bean when we request it, not at application startup.

Essa anotação se comporta de maneira diferente, dependendo de onde a colocamos exatamente. Podemos colocar:

  • um método de fábrica de bean anotado@Bean, para atrasar a chamada do método (daí a criação do bean)

  • uma classe @Configuration e todos os métodos@Bean contidos serão afetados

  • uma classe@Component, que não é uma classe@Configuration, este bean será inicializado lentamente

  • um construtor, setter ou campo@Autowired para carregar a própria dependência lentamente (via proxy)

Esta anotação possui um argumento denominadovalue com o valor padrão detrue. É útil substituir o comportamento padrão.

Por exemplo, marcar os beans para serem carregados antecipadamente quando a configuração global for lenta ou configurar métodos@Bean específicos para carregamento antecipado em uma classe@Configuration marcada com@Lazy:

@Configuration
@Lazy
class VehicleFactoryConfig {

    @Bean
    @Lazy(false)
    Engine engine() {
        return new Engine();
    }
}

Para ler mais, visitethis article.

2.8. @Lookup

Um método anotado com@Lookup diz ao Spring para retornar uma instância do tipo de retorno do método quando o invocarmos.

Informações detalhadas sobre a anotaçãocan be found in this article.

2.9. @Primary

Às vezes, precisamos definir vários beans do mesmo tipo. Nesses casos, a injeção não terá êxito porque o Spring não tem idéia de qual feijão precisamos.

Já vimos uma opção para lidar com este cenário: marcar todos os pontos de fiação com@Qualifiere especificar o nome do bean necessário.

No entanto, na maioria das vezes precisamos de um bean específico e raramente dos outros. Podemos usar@Primary para simplificar este caso: sewe mark the most frequently used bean with @Primary, será escolhido em pontos de injeção não qualificados:

@Component
@Primary
class Car implements Vehicle {}

@Component
class Bike implements Vehicle {}

@Component
class Driver {
    @Autowired
    Vehicle vehicle;
}

@Component
class Biker {
    @Autowired
    @Qualifier("bike")
    Vehicle vehicle;
}

No exemplo anterior,Car é o veículo principal. Portanto, na classeDriver, o Spring injeta um beanCar. Claro, no beanBiker, o valor do campovehicle será um objetoBike porque é qualificado.

2.10. @Scope

Usamos@Scope para definir oscope de uma classe@Component ou uma definição@Bean.. Pode sersingleton, prototype, request, session, globalSession ou algum escopo personalizado.

Por exemplo:

@Component
@Scope("prototype")
class Engine {}

3. Anotações de configuração de contexto

Podemos configurar o contexto do aplicativo com as anotações descritas nesta seção.

3.1. @Profile

Se quisermos que o Spring sejause a @Component class or a @Bean method only when a specific profile is active, podemos marcá-lo com@Profile. Podemos configurar o nome do perfil com o argumentovalue da anotação:

@Component
@Profile("sportDay")
class Bike implements Vehicle {}

Você pode ler mais sobre perfis emthis article.

3.2. @Import

Podemos usarspecific @Configuration classes without component scanning com esta anotação. Podemos fornecer a essas classes o argumento@Import'svalue:

@Import(VehiclePartSupplier.class)
class VehicleFactoryConfig {}

3.3. @ImportResource

Podemosimport XML configurations com esta anotação. Podemos especificar os locais do arquivo XML com o argumentolocations, ou com seu alias, o argumentovalue:

@Configuration
@ImportResource("classpath:/annotations.xml")
class VehicleFactoryConfig {}

3.4. @PropertySource

Com esta anotação, podemosdefine property files for application settings:

@Configuration
@PropertySource("classpath:/annotations.properties")
class VehicleFactoryConfig {}

@PropertySource aproveita o recurso de anotações repetidas do Java 8, o que significa que podemos marcar uma classe com ele várias vezes:

@Configuration
@PropertySource("classpath:/annotations.properties")
@PropertySource("classpath:/vehicle-factory.properties")
class VehicleFactoryConfig {}

3.5. @PropertySources

Podemos usar esta anotação para especificar várias configurações de@PropertySource:

@Configuration
@PropertySources({
    @PropertySource("classpath:/annotations.properties"),
    @PropertySource("classpath:/vehicle-factory.properties")
})
class VehicleFactoryConfig {}

Observe que, desde o Java 8, podemos obter o mesmo com o recurso de anotações repetidas, conforme descrito acima.

4. Conclusão

Neste artigo, vimos uma visão geral das anotações principais do Spring mais comuns. Vimos como configurar a fiação do bean e o contexto do aplicativo e como marcar as classes para a varredura de componentes.

Como de costume, os exemplos estão disponíveisover on GitHub.