Adnotări de bază de primăvară

Acest articol face parte dintr-o serie: • Adnotări de bază de primăvară (articolul actual) • Adnotări de web de primăvară

• Adnotări de primăvară

• Adnotări de programare de primăvară

• Adnotări de date de primăvară

• Adnotări de fasole de primăvară

1. Prezentare generală

Putem utiliza capacitățile motorului de primăvară DI folosind adnotările în org.springframework.beans.factory.annotation și org.springframework.context.annotation pachete.

Adesea numim aceste „adnotări de bază de primăvară” și le vom examina în acest tutorial.

2. Adnotări legate de DI

2.1. @Autowired

Putem folosi @Autowired pentru a marca o dependență pe care Spring o va rezolva și o va injecta . Putem folosi această adnotare cu un constructor, un setter sau o injecție de câmp.

Injecție constructor:

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

Injecție setter:

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

Injecție de câmp:

class Car { @Autowired Engine engine; }

@Autowired are un argument boolean numit necesar cu o valoare implicită true . Reglează comportamentul primăverii atunci când nu găsește o bobă potrivită. Când este adevărat , se aruncă o excepție, în caz contrar, nimic nu este conectat.

Rețineți că, dacă folosim injecția constructorului, toate argumentele constructorului sunt obligatorii.

Începând cu versiunea 4.3, nu este necesar să adnotăm constructorii cu @Autowired în mod explicit, cu excepția cazului în care declarăm cel puțin doi constructori.

Pentru mai multe detalii, vizitați articolele noastre despre @Autowired și injecția constructorului.

2.2. @Fasole

@Bean marchează o metodă din fabrică care instantaneează un bob de primăvară:

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

Spring apelează aceste metode atunci când este necesară o nouă instanță de tip return.

Bobul rezultat are același nume ca și metoda din fabrică. Dacă vrem să o numim diferit, o putem face cu numele sau argumentele valorice ale acestei adnotări ( valoarea argumentului este un alias pentru numele argumentului ):

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

Rețineți că toate metodele adnotate cu @Bean trebuie să fie în clasele @Configuration .

2.3. @Calificator

Folosim @Qualifier împreună cu @Autowired pentru a furniza ID-ul de fasole sau numele de fasole pe care dorim să îl folosim în situații ambigue.

De exemplu, următoarele două bean implementează aceeași interfață:

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

Dacă Spring trebuie să injecteze un bob de vehicul , acesta va avea mai multe definiții potrivite. În astfel de cazuri, putem furniza numele unui bean în mod explicit folosind adnotarea @Qualifier .

Utilizarea injecției constructor:

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

Utilizarea injecției setter:

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

Alternativ:

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

Utilizarea injecției de câmp:

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

Pentru o descriere mai detaliată, vă rugăm să citiți acest articol.

2.4. @Necesar

@Necesar metodele setter pentru a marca dependențele pe care dorim să le populăm prin XML:

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

În caz contrar, BeanInitializationException va fi aruncat.

2.5. @Valoare

Putem folosi @Value pentru injectarea valorilor proprietăților în fasole. Este compatibil cu constructorul, setterul și injecția de câmp.

Injecție constructor:

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

Injecție setter:

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

Alternativ:

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

Injecție de câmp:

@Value("8") int cylinderCount;

Desigur, injectarea valorilor statice nu este utilă. Prin urmare, putem folosi siruri de caractere substituent în @Value la valorile de sârmă definite la surse externe , de exemplu, în .properties sau .yaml fișiere.

Să presupunem următorul fișier .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 valorifică caracteristica de adnotări repetate Java 8, ceea ce înseamnă că putem marca o clasă cu ea de mai multe ori:

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

3.5. @PropertySources

Putem folosi această adnotare pentru a specifica mai multe configurații @PropertySource :

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

Rețineți că, din Java 8, putem obține același lucru cu caracteristica de adnotări repetate, așa cum este descris mai sus.

4. Concluzie

În acest articol, am văzut o prezentare generală a celor mai comune adnotări de bază de primăvară. Am văzut cum să configurăm cablarea bean și contextul aplicației și cum să marcăm clasele pentru scanarea componentelor.

Ca de obicei, exemplele sunt disponibile pe GitHub.

Următorul » Adnotări web de primăvară