Anotasi Teras Musim Bunga

Artikel ini adalah sebahagian daripada siri: • Anotasi Inti Musim Bunga (artikel semasa) • Anotasi Web Musim Semi

• Anotasi Boot Musim Semi

• Anotasi Penjadualan Musim Bunga

• Anotasi Data Musim Semi

• Anotasi Kacang Musim Bunga

1. Gambaran keseluruhan

Kita boleh memanfaatkan keupayaan enjin Spring DI menggunakan anotasi dalam org.springframework.beans.factory.annotation dan org.springframework.context.annotation pakej.

Kami sering menyebutnya sebagai "anotasi inti musim bunga" dan kami akan menyemaknya dalam tutorial ini.

2. Anotasi Berkaitan DI

2.1. @Autowired

Kita boleh menggunakan @Autowired untuk menandakan pergantungan yang akan diselesaikan dan disuntik oleh Spring . Kami boleh menggunakan anotasi ini dengan konstruktor, pengatur, atau suntikan medan.

Suntikan konstruktor:

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

Suntikan setter:

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

Suntikan lapangan:

class Car { @Autowired Engine engine; }

@Autowired mempunyai argumen boolean yang disebut diperlukan dengan nilai lalai dari true . Ini menyesuaikan tingkah laku Spring apabila tidak menemui kacang yang sesuai untuk dawai. Apabila benar , pengecualian dilemparkan, jika tidak, tidak ada yang disambungkan.

Perhatikan, bahawa jika kita menggunakan suntikan konstruktor, semua argumen konstruktor adalah wajib.

Bermula dengan versi 4.3, kami tidak perlu memberi penjelasan kepada pembina dengan @Autowired secara eksplisit melainkan kami menyatakan sekurang-kurangnya dua pembina.

Untuk maklumat lebih lanjut, kunjungi artikel kami mengenai @Autowired dan suntikan konstruktor.

2.2. @Bean

@Bean menandakan kaedah kilang yang menunjukkan kacang Spring:

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

Spring memanggil kaedah ini apabila contoh baru dari jenis pengembalian diperlukan.

Kacang yang dihasilkan mempunyai nama yang sama dengan kaedah kilang. Jika kita mahu nama itu berbeza, kita boleh berbuat demikian dengan nama atau nilai hujah anotasi ini (hujah nilai adalah alias untuk hujah nama ):

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

Perhatikan, bahawa semua kaedah yang dianotasi dengan @Bean mesti ada di kelas @Konfigurasi .

2.3. @Kelayakan

Kami menggunakan @Qualifier bersama dengan @Autowired untuk memberikan id kacang atau nama kacang yang ingin kami gunakan dalam situasi samar-samar.

Sebagai contoh, dua biji berikut menerapkan antara muka yang sama:

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

Sekiranya Spring perlu menyuntik kacang kenderaan , ia akan berakhir dengan beberapa definisi yang sepadan. Dalam kes seperti itu, kami dapat memberikan nama kacang secara eksplisit menggunakan anotasi @Qualifier .

Menggunakan suntikan konstruktor:

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

Menggunakan suntikan setter:

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

Sebagai alternatif:

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

Menggunakan suntikan medan:

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

Untuk keterangan yang lebih terperinci, sila baca artikel ini.

2.4. @ Diperlukan

@ Diperlukan kaedah setter untuk menandakan pergantungan yang ingin kami isi melalui XML:

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

Jika tidak, BeanInitializationException akan dilemparkan.

2.5. @Nilai

Kita boleh menggunakan @Value untuk memasukkan nilai harta tanah ke dalam kacang. Ia sesuai dengan konstruktor, setter, dan suntikan lapangan.

Suntikan konstruktor:

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

Suntikan setter:

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

Sebagai alternatif:

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

Suntikan lapangan:

@Value("8") int cylinderCount;

Sudah tentu, menyuntikkan nilai statik tidak berguna. Oleh itu, kita boleh menggunakan tali pemegang tempat di @value kepada nilai wayar ditakrifkan dalam sumber-sumber luar , sebagai contoh, di .properties atau .yaml fail.

Mari kita anggap fail .properties berikut :

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 memanfaatkan ciri anotasi berulang Java 8, yang bermaksud kita dapat menandakan kelas dengannya berulang kali:

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

3.5. @PropertySources

Kami boleh menggunakan anotasi ini untuk menentukan beberapa konfigurasi @PropertySource :

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

Perhatikan, bahawa sejak Java 8 kita dapat mencapai hal yang sama dengan fitur anotasi berulang seperti yang dijelaskan di atas.

4. Kesimpulan

Dalam artikel ini, kami melihat gambaran keseluruhan anotasi inti Spring yang paling biasa. Kami melihat bagaimana mengkonfigurasi pendawaian kacang dan konteks aplikasi, dan bagaimana menandakan kelas untuk pengimbasan komponen.

Seperti biasa, contohnya terdapat di GitHub.

Seterusnya » Anotasi Web Musim Semi