Пролетни основни анотации

Тази статия е част от поредица: • Spring Core Annotations (текуща статия) • Spring Web Annotations

• Анотации на пролетното зареждане

• Анотации за пролетно планиране

• Пролетни анотации на данни

• Анотации на пролетен боб

1. Общ преглед

Можем да използваме възможностите на Spring DI двигателя, като използваме анотациите в пакетите org.springframework.beans.factory.annotation и org.springframework.context.annotation .

Често ги наричаме „Spring core annotations“ и ще ги прегледаме в този урок.

2. Анотации, свързани с DI

2.1. @Autowired

Можем да използваме @Autowired, за да маркираме зависимост, която Spring ще разреши и инжектира . Можем да използваме тази анотация с конструктор, сетер или инжектиране на поле.

Впръскване на конструктор:

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

Инжектиране на сетер:

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

Полево инжектиране:

class Car { @Autowired Engine engine; }

@Autowired има булев аргумент, наречен задължителен със стойност по подразбиране true . Той настройва поведението на Spring, когато не намери подходящ боб за свързване. Когато е вярно , се хвърля изключение, в противен случай нищо не е свързано.

Имайте предвид, че ако използваме инжектиране на конструктор, всички аргументи на конструктора са задължителни.

Започвайки с версия 4.3, не е необходимо да коментираме конструкторите с @Autowired изрично, освен ако не декларираме поне два конструктора.

За повече подробности посетете нашите статии за @Autowired и инжектиране на конструктор.

2.2. @Bean

@Bean маркира фабричен метод, който създава екземпляр Spring bean:

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

Spring извиква тези методи, когато се изисква нов екземпляр от типа връщане.

Полученият боб има същото име като фабричния метод. Ако искаме да го наименуваме по различен начин, можем да го направим с името или аргументите за стойност на тази анотация ( стойността на аргумента е псевдоним за името на аргумента ):

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

Имайте предвид, че всички методи, коментирани с @Bean, трябва да са в класове @Configuration .

2.3. @ Квалификатор

Използваме @Qualifier заедно с @Autowired, за да предоставим идентификатора на боб или името на боб, което искаме да използваме в двусмислени ситуации.

Например, следните два компонента изпълняват един и същ интерфейс:

class Bike implements Vehicle {} class Car implements Vehicle {}

Ако Spring трябва да инжектира Bean на превозно средство , той завършва с множество съвпадащи дефиниции. В такива случаи можем да предоставим името на боб изрично, като използваме анотацията @Qualifier .

Използване на инжектор на конструктор:

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

Използване на инжектиране на сетер:

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

Алтернативно:

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

Използване на полево инжектиране:

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

За по-подробно описание, моля, прочетете тази статия.

2.4. @ Задължително

@ Изисква се за методи на задаване за маркиране на зависимости, които искаме да попълним чрез XML:

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

В противен случай ще бъде хвърлен BeanInitializationException .

2.5. @ Стойност

Можем да използваме @Value за инжектиране на стойности на свойства в зърна. Съвместим е с конструктор, сетер и инжектиране на поле.

Впръскване на конструктор:

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

Инжектиране на сетер:

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

Алтернативно:

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

Полево инжектиране:

@Value("8") int cylinderCount;

Разбира се, инжектирането на статични стойности не е полезно. Следователно можем да използваме низове за заместващи елементи в @Value за стойности на проводници, дефинирани във външни източници , например в .properties или .yaml файлове.

Нека приемем следния файл .properties :

engine.fuelType=petrol

We can inject the value of engine.fuelType with the following:

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

We can use @Value even with SpEL. More advanced examples can be found in our article about @Value.

2.6. @DependsOn

We can use this annotation to make Spring initialize other beans before the annotated one. Usually, this behavior is automatic, based on the explicit dependencies between beans.

We only need this annotation when the dependencies are implicit, for example, JDBC driver loading or static variable initialization.

We can use @DependsOn on the dependent class specifying the names of the dependency beans. The annotation's value argument needs an array containing the dependency bean names:

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

Alternatively, if we define a bean with the @Bean annotation, the factory method should be annotated with @DependsOn:

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

2.7. @Lazy

We use @Lazy when we want to initialize our bean lazily. By default, Spring creates all singleton beans eagerly at the startup/bootstrapping of the application context.

However, there are cases when we need to create a bean when we request it, not at application startup.

This annotation behaves differently depending on where we exactly place it. We can put it on:

  • a @Bean annotated bean factory method, to delay the method call (hence the bean creation)
  • a @Configuration class and all contained @Bean methods will be affected
  • a @Component class, which is not a @Configuration class, this bean will be initialized lazily
  • an @Autowired constructor, setter, or field, to load the dependency itself lazily (via proxy)

This annotation has an argument named value with the default value of true. It is useful to override the default behavior.

For example, marking beans to be eagerly loaded when the global setting is lazy, or configure specific @Bean methods to eager loading in a @Configuration class marked with @Lazy:

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

For further reading, please visit this article.

2.8. @Lookup

A method annotated with @Lookup tells Spring to return an instance of the method’s return type when we invoke it.

Detailed information about the annotation can be found in this article.

2.9. @Primary

Sometimes we need to define multiple beans of the same type. In these cases, the injection will be unsuccessful because Spring has no clue which bean we need.

We already saw an option to deal with this scenario: marking all the wiring points with @Qualifier and specify the name of the required bean.

However, most of the time we need a specific bean and rarely the others. We can use @Primary to simplify this case: if we mark the most frequently used bean with @Primary it will be chosen on unqualified injection points:

@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; }

In the previous example Car is the primary vehicle. Therefore, in the Driver class, Spring injects a Car bean. Of course, in the Biker bean, the value of the field vehicle will be a Bike object because it's qualified.

2.10. @Scope

We use @Scope to define the scope of a @Component class or a @Bean definition. It can be either singleton, prototype, request, session, globalSession or some custom scope.

For example:

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

3. Context Configuration Annotations

We can configure the application context with the annotations described in this section.

3.1. @Profile

If we want Spring to use a @Component class or a @Bean method only when a specific profile is active, we can mark it with @Profile. We can configure the name of the profile with the value argument of the annotation:

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

You can read more about profiles in this article.

3.2. @Import

We can use specific @Configuration classes without component scanning with this annotation. We can provide those classes with @Import‘s value argument:

@Import(VehiclePartSupplier.class) class VehicleFactoryConfig {}

3.3. @ImportResource

We can import XML configurations with this annotation. We can specify the XML file locations with the locations argument, or with its alias, the value argument:

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

3.4. @PropertySource

With this annotation, we can define property files for application settings:

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

@PropertySource използва функцията за повтарящи се анотации на Java 8, което означава, че можем да маркираме клас с нея няколко пъти:

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

3.5. @PropertySources

Можем да използваме тази анотация, за да посочим множество конфигурации @PropertySource :

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

Имайте предвид, че от Java 8 можем да постигнем същото с функцията за повтарящи се анотации, както е описано по-горе.

4. Заключение

В тази статия видяхме преглед на най-често срещаните анотации на Spring. Видяхме как да конфигурираме bean окабеляването и контекста на приложението и как да маркираме класове за сканиране на компоненти.

Както обикновено, примерите са достъпни в GitHub.

Напред » Пролетни уеб анотации