Spring Framework'te @Inject ve @Autowired arasındaki fark nedir? Hangisi hangi şartlar altında kullanılır?


695

SpringSource'daki bazı bloglardan geçiyorum ve bloglardan birinde yazar kullanıyor @Injectve sanırım da kullanabilir @Autowired.

İşte kod parçası:

@Inject private CustomerOrderService customerOrderService;

Ben arasındaki fark hakkında değil eminim @Injectve @Autowiredve birisi kendi farkını açıkladı eğer bunu takdir ediyorum ve hangisinin neyi durumun altında kullanılır?


3
Bu konuda yeni olduğum için bir cevabım yok, ancak bu sakaenakajima.wordpress.com/2010/08/10/…
Sagar V


2
'@Inject' ve '@Autowired' arasındaki fark bu makalede iyi açıklanmıştır alextheedom.wordpress.com/2016/02/13/…
Alex Theedom

Yanıtlar:


720

Burada, javax.inject.Injectek açıklamalara atıfta bulunduğunuzu varsayarsak . Java EE 6'da (JSR-299) tanıtılan @InjectJava CDI ( Bağlamlar ve Bağımlılık Enjeksiyonu ) standardının bir parçasıdır, daha fazlasını oku . Spring, @Injectkendi @Autowiredek açıklamalarıyla eşanlamlı olarak kullanmayı desteklemeyi seçti .

Bu nedenle, sorunuzu cevaplamak için @AutowiredSpring'in kendi açıklamasıdır. @Inject, Spring'e benzer bir bağımlılık enjeksiyonu standardını tanımlayan CDI adı verilen yeni bir Java teknolojisinin bir parçasıdır. Bir Spring uygulamasında, iki ek açıklama, Spring'in kendilerine ek olarak bazı JSR-299 ek açıklamalarını desteklemeye karar vermesiyle aynı şekilde çalışır.


115
Teoride, eğer @Inject kullandıysanız, yayı başka bir DI çerçevesiyle (örneğin, Guice) değiştirebilir ve bağımlılıklarınızı aynı şekilde enjekte edebilirsiniz.
Alex Barnes

71
Bilgiçlik riski altında: @InjectCDI'den (JSR-299) ayrı bir JSR'dir (JSR-330).
Brad Cupit

36
Eğer JSR- güvenirse * ek açıklamalar sadece, tabi, olabilir size DI çerçevesini değiştirin. Ama yapacak mısın? İlkbahar kullanmaya başladıktan sonra, sadece DI'dan çok daha fazla kullanmış olabilirsiniz. Sadece bir değişiklik yapmazsınız; ve bunu yapsanız bile, hareketi yapacak veya bozacak birkaç arama ve yer değiştirme değildir. Öte yandan, Spring'in kendi ek açıklamaları size çok daha fazla işlevsellik sunuyor. İyi bir çerçeveye hakim olmak size pek çok şeyi kullanmaktan daha fazlasını verecektir.
Agoston Horvath

18
DI çerçevelerini sık sık değiştirmeyeceğimizi kabul ediyorum. Ancak, kaynak kodumuzda birden fazla paket varsa ve birden fazla proje arasında paylaşmak istediğiniz ortak bir paket oluşturmak ve sonra @InjectJSR ek açıklama ile gitmek @Autowiredistiyorsanız, kod tabanınızı yay DI ile kilitleyen kullanmaktan daha iyidir .
Aditya

3
Tek @Injectbaşına kullanmak çerçeve bağımsızlığını garanti etmez. Ayrıca Spring @Componentveya gibi çerçeve bağımlı mekanizmalar olmadan enjekte edilebilir fasulye beyan etmek gerekir application.xml, ama kullanımı @Namedve @Singletonsınıf düzeyinde. Herhangi bir Bahar projesi gerçekten böyle fasulye ilan ederse, hiç bir fikrim yok - İlkbahardan JEE'ye göç eden herhangi bir projeyi bile duymadım ...
Marcus K.

162

İşte olan blog yazısı karşılaştırır @Resource, @Injectve @Autowiredve oldukça kapsamlı bir iş yapmak gibi görünüyor.

Bağlantıdan:

Test 2 ve 7 hariç, konfigürasyon ve sonuçlar aynıydı. Başlığın altına baktığımda '@Autowired' ve '@Inject' ek açıklamasının aynı şekilde davrandığını belirledim. Bu ek açıklamaların her ikisi de bağımlılıkları enjekte etmek için 'AutowiredAnnotationBeanPostProcessor' kullanır. '@Autowired' ve '@Inject', Bahar çekirdeklerini enjekte etmek için değiştirilebilir. Ancak '@Resource' ek açıklaması bağımlılıkları enjekte etmek için 'CommonAnnotationBeanPostProcessor'u kullanır. Farklı post işlemci sınıfları kullanıyor olsalar da, hepsi neredeyse aynı şekilde davranıyor. Aşağıda, yürütme yollarının bir özeti verilmiştir.

Test 2 ve 7, yazarın referans aldığı 'alan adına göre enjeksiyon' ve 'kötü bir niteleyici kullanarak bir fasulyeyi çözme girişimi' dir.

Sonuç size ihtiyacınız olan tüm bilgileri vermelidir.


4
Bu makale üç ek açıklamanın büyük bir açıklamasıdır. İlk kaydırmadan sonra tekrar okumak zorunda kaldım; ama mükemmel bir makale.
Thomas

1
Çok teşekkürler! Makale, Spring ve JavaEE arasındaki farklılıkları ve benzerlikleri bulma arayışımdaki cevaplarımın yanı sıra birkaç sorum daha yanıtladı.
Kevin Cruijssen

36

Kablolamanın olmadığı durumlarla başa çıkmak için, @Autowired requiredözellik olarak ayarlanmış fasulye mevcuttur false.

Ancak kullanırken @Inject, Sağlayıcı arayüzü fasulye ile çalışır, yani fasulyeye doğrudan değil Sağlayıcıya enjekte edilir.


8
Bu çok önemlidir ve en çok dile getirilen cevaplarda göz ardı edilmiştir.
Igor Donin

Varsayılan olarak, Autowired için gerekli parametre true değerine ayarlanır. Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
sakin

25

Spring 3.0 itibariyle Yay teklifleri JSR-330 bağımlılık enjeksiyon ek açıklamalar için destek ( @Inject, @Named, @Singleton).

Bir yoktur Bahar belgelerinde ayrı bir bölüm kendi Bahar eşdeğerlerine karşılaştırmaları da dahil onlar hakkında.


Burada soru, Spring'in JSR'yi desteklediğini söylediğinde ne demek istiyorsun? Kap, Bahar'dan bağımsız JSR'yi ve kapın J2EE uyumlu olması için bir gereksinimi desteklemiyor mu? Yani işlevselliği sarar mı? Bahar bunu desteklemeseydi, javax'tan gelen ek açıklama varsayılan olarak hala çalışmaz mı?
Dan Chase

Spring'i bir JEE kapsayıcısında çalıştırmak şart değil, Tomcat gibi bir sunucu uygulaması / JSP kapsayıcısında da kullanabilir ve yine de JSR-330 desteğine sahip olabilirsiniz. Bahar ayrı bir DI kapsayıcısıdır, CDI çekirdeklerini ana JEE sunucusu ile "değiş tokuş etmez" ise, bu demek istediğiniz şeydir. CDI'yi bir JEE kabında veya Bahar fasulyesinde kullanabilirsiniz - ancak ikisini de kullanamazsınız (kutunun dışında).
Andre Steingress

22

(Okurken fark temel fark Bahar Dokümanlar arasında) @Autowiredve @Injectyani @Autowired@ Enjekte hiçbir özelliği 'ni gerekli' ederken 'Gerekli' niteliği taşır.


ne demek istiyorsun?
mattyman

2
@mattymanme "Aday fasulye her kullanılabilir olduğunda varsayılan olarak otomatik kablolama başarısız olur; varsayılan davranış, ek açıklamalı yöntemleri, yapıcıları ve alanları gerekli bağımlılıkları gösterecek şekilde işlemektir. Bu davranış, gerekli özniteliği false olarak ayarlayarak değiştirilebilir. ". Örneğin :.@Autowired(required=false) Basit bir ifadeyle, " requiredÖzellik, özelliğin otomatik kablolama amaçları için gerekli olmadığını belirtir; özellik, otomatik kablolama yapılamıyorsa yoksayılır."
Şanslı

kaynak koduna bak genel arabirim Autowired {/ ** * Ek açıklamalı bağımlılığın gerekli olup olmadığını belirtir. * / boolean gerekli () varsayılan true; } ortak arabirim Inject {}
tarn

15

Her zaman daha iyi kullanın. Çünkü uygulamamızı çerçeveye agnostik yapan java konfigürasyon yaklaşımı (güneş tarafından sağlanan). Yani eğer bahar yaparsanız sınıflarınız da işe yarayacaktır.

@Autowired kullanırsanız, yalnızca yay ile çalışır çünkü @Autowired yay tarafından sağlanan ek açıklamadır.


13
Güneş öldü. Yaşasın güneş.
Amrinder Arora

6
çerçeveyi ne sıklıkla değiştireceksiniz? sadece merak
Kay

Çoğu projede Inject yerine Autowired'i gördüm. Cevabın mantığını anlıyorum ama oy kullanamıyorum.
Witold Kaczurba

13

@Autowired ek açıklama Bahar çerçevesinde tanımlanır.

@Injectek açıklama standart "Java için Bağımlılık Enjeksiyonu" (JSR-330) ile tanımlanan standart bir ek açıklamadır . Yay (3.0 sürümünden beri), standart JSR-330'da tanımlanan genel bağımlılık enjeksiyon modelini destekler. ( Google Guice çerçeveleri ve Picocontainer çerçevesi de bu modeli desteklemektedir).

İle ertelenmiş referansların enjekte edilmesine izin veren arayüzün @Injectuygulanmasına referans enjekte edilebilir Provider.

Ek açıklamalar @Injectve @Autowired- neredeyse tam benzetmelerdir. @AutowiredEk açıklamanın yanı sıra ek @Injectaçıklama otomatik ciltleme özellikleri, yöntemleri ve yapıcıları için kullanılabilir.

@AutowiredEk açıklamanın aksine ek @Injectaçıklamanın hiçbir requiredözelliği yoktur . Bu nedenle, bağımlılıklar bulunmazsa - bir istisna atılır.

Bağlanma özelliklerinin açıklamalarında da farklılıklar vardır. Enjeksiyon için bileşen seçiminde belirsizlik varsa @Namedniteleyici eklenmelidir. @AutowiredEk açıklama için benzer bir durumda @Qualifierniteleyici eklenecektir (JSR-330 kendi @Qualifierek açıklamasını tanımlar ve bu niteleyici ek açıklaması @Namedtanımlanır).


'@Inject' gerekli bir özniteliğe sahip olmasa da Java Docs durumu: '@Inject' ile açıklamalı üyelerin enjeksiyonu gerekir. Bu da eğer bir üye bulunmazsa enjekte edilmesinin başarısız olacağı anlamına gelir. Bkz. Java Belgeleri: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom


12

Yukarıdakilere ek olarak:

  1. @AutowiredFasulye için varsayılan kapsam Singleton'dur , JSR 330 @Injectek açıklaması kullanıldığında Spring'in prototipi gibidir .
  2. JSR 330 kullanarak @Lazy eşdeğeri yoktur @Inject.
  3. JSR 330 kullanarak @Value eşdeğeri yoktur @Inject.

0

@InjectEk açıklama JSR-330 ek açıklamaları koleksiyonu biridir. Bu, Türe Göre Eşleştirme, Niteleyere Göre Eşleştirme, Ada Göre Eşleştirme yürütme yollarına sahiptir. Bu yürütme yolları hem ayarlayıcı hem de alan enjeksiyonu için geçerlidir. @AutowiredEk açıklama davranışı, ek açıklama ile aynıdır @Inject. Tek fark, @Autowiredek açıklama Bahar çerçevesinin bir parçasıdır. @Autowiredek açıklama yukarıdaki yürütme yollarına da sahiptir. Bu yüzden @Autowiredcevabınız için tavsiye ederim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.