Jak działa autowiringowanie wiosną?

Jestem trochę zdezorientowany, jak inwersja sterowania (IoC) działa w Spring.

Powiedzmy, że mam klasę usług o nazwie UserServiceImpl, która implementuje interfejs UserService.

Jak by to było @Autowired?

I w moim Controllers, jak miałbym instantiate BYĆ instance z tej służby?

Czy mógłbym po prostu zrobić co następuje?

UserService userService = new UserServiceImpl();
Author: Mahozad, 2010-07-01

9 answers

Po pierwsze i najważniejsze - wszystkie fasolki są zarządzane - "żyją" w kontenerze, zwanym "kontekstem aplikacji".

Po drugie, każda aplikacja ma punkt wejścia do tego kontekstu. Aplikacje internetowe mają Servlet, JSF używa el-resolver, itp. Istnieje również miejsce, w którym kontekst aplikacji jest bootstrapped i wszystkie fasolki-autowired. W aplikacjach internetowych może to być słuchacz startowy.

Autowirowanie odbywa się poprzez umieszczenie instancji jednej fasoli w pożądane pole w przypadku innej fasoli. Obie klasy powinny być beansami, tzn. powinny być zdefiniowane w kontekście aplikacji.

Czym jest "życie" w kontekście aplikacji? Oznacza to, że kontekst tworzy instancje obiektów, a nie Ciebie. Tzn. - you never make new UserServiceImpl() - kontener znajduje każdy punkt wtrysku i ustawia tam instancję.

W kontrolerach masz po prostu:

@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {

    // Tells the application context to inject an instance of UserService here
    @Autowired
    private UserService userService;

    @RequestMapping("/login")
    public void login(@RequestParam("username") String username,
           @RequestParam("password") String password) {

        // The UserServiceImpl is already injected and you can use it
        userService.login(username, password);

    }
}

Kilka uwag:

  • W Twój applicationContext.xml powinieneś włączyć <context:component-scan>, Aby klasy były skanowane pod kątem @Controller, @Service, itd. Przypisy
  • punktem wejścia dla aplikacji Spring-MVC jest DispatcherServlet, ale jest on ukryty przed tobą, a zatem bezpośrednia interakcja i bootstrapowanie kontekstu aplikacji odbywa się za sceną.
  • UserServiceImpl należy również zdefiniować jako bean-albo za pomocą <bean id=".." class=".."> lub za pomocą adnotacji @Service. Ponieważ będzie jedynym wykonawcą UserService, będzie wstrzyknięcie.
  • oprócz adnotacji @Autowired, Spring może używać autowiringu konfigurowalnego w XML. W takim przypadku wszystkie pola, które mają nazwę lub typ pasujący do istniejącej fasoli, są automatycznie wstrzykiwane. W rzeczywistości taki był początkowy pomysł autowiringu - aby pola były wstrzykiwane z zależnościami bez żadnej konfiguracji. Inne adnotacje jak @Inject, @Resource może być również używany.
 606
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-12 18:32:32

Zależy od tego, czy przeszedłeś trasę adnotacji, czy trasę definicji XML bean.

Powiedz, że masz fasolę zdefiniowaną w twoim applicationContext.xml:

<beans ...>

    <bean id="userService" class="com.foo.UserServiceImpl"/>

    <bean id="fooController" class="com.foo.FooController"/>

</beans>

Autowirowanie następuje po uruchomieniu aplikacji. Więc w fooController, która dla argumentów chce używać klasy UserServiceImpl, dodałbyś ją w następujący sposób:

public class FooController {

    // You could also annotate the setUserService method instead of this
    @Autowired
    private UserService userService;

    // rest of class goes here
}

Gdy zobaczy @Autowired, Spring będzie szukał klasy, która pasuje do właściwości w applicationContext i wstrzyknie ją automatycznie. Jeśli u pacjenta występuje więcej niż 1 UserService bean, wtedy będziesz musiał zakwalifikować, który z nich powinien użyć.

Jeśli wykonasz następujące czynności:

UserService service = new UserServiceImpl();

Nie odbierze @Autowired, chyba że sam go ustawisz.

 60
Author: Ben J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-30 21:37:26

@Autowired jest adnotacją wprowadzoną wiosną 2.5 i jest używana tylko do iniekcji.

Na przykład:

class A {

    private int id;

    // With setter and getter method
}

class B {

    private String name;

    @Autowired // Here we are injecting instance of Class A into class B so that you can use 'a' for accessing A's instance variables and methods.
    A a;

    // With setter and getter method

    public void showDetail() {
        System.out.println("Value of id form A class" + a.getId(););
    }
}
 18
Author: mohit bansal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 18:37:45

Jak @Autowired działa wewnętrznie?

Ex -

class EnglishGreeting {
   private Greeting greeting;
   //setter and getter
}

class Greeting {
   private String message;
   //setter and getter
}

.plik xml będzie wyglądał podobnie, jeśli nie zostanie użyty @Autowired

<bean id="englishGreeting" class="com.bean.EnglishGreeting">
   <property name="greeting" ref="greeting"/>
</bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

Jeśli używasz @ Autowired to

class EnglishGreeting {
   @Autowired //so automatically based on the name it will identify the bean and inject.
   private Greeting greeting;
   //setter and getter
}

.plik xml będzie wyglądał podobnie, jeśli nie zostanie użyty @Autowired

<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>

<bean id="greeting" class="com.bean.Greeting">
   <property name="message" value="Hello World"/>
</bean>

Jeśli nadal masz wątpliwości, przejdź poniżej demo na żywo

Jak działa @Autowired wewnętrznie ?

 8
Author: jeet singh parmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 08:55:07

@ Autowired

  • Oznacza konstruktor, pole, metodę setter lub metodę config jako / align = "left" / Linear

  • Tylko jeden konstruktor (maksymalnie) danej klasy bean może to adnotacja, wskazująca konstruktor do autowire, gdy jest używany jako Wiosenna fasola. Taki konstruktor nie musi być publiczny.

  • Pola są wstrzykiwane zaraz po zbudowaniu fasoli, przed jakąkolwiek wywoływane są metody konfiguracji. Takie pole konfiguracyjne nie musi być publiczne.

  • Metody Config mogą mieć dowolną nazwę i dowolną liczbę argumenty; każdy z tych argumentów zostanie automatycznie połączony z dopasowaniem fasola w wiosennym pojemniku. Metody setera właściwości fasoli są właściwie to tylko szczególny przypadek takiej ogólnej metody konfiguracji. Takie metody konfiguracji nie muszą być publiczne.

  • W przypadku wielu metod argumentowych parametr "required" jest dotyczy wszystkich argumenty.

  • W przypadku typu zależności kolekcji lub mapy, kontener będzie autowire wszystkie fasolki pasujące do deklarowanego typu wartości. W przypadku Map, klucze muszą być zadeklarowane jako type String i zostaną rozwiązane na odpowiednie nazwy fasoli.

 7
Author: nijogeorgep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 09:51:59

Wystarczy dodać adnotację do klasy usług UserServiceImpl za pomocą adnotacji

@Service("userService")

Spring container zajmie się cyklem życia tej klasy, ponieważ rejestruje się jako usługa.

Następnie w kontrolerze można go auto wire (utworzyć instancję) i korzystać z jego funkcjonalności.

@Autowired
UserService userService;
 4
Author: Jitender Chahar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-18 09:47:28

Spring dependency inject pomaga usunąć sprzężenie z klas. Zamiast tworzyć obiekt w ten sposób

UserService userService = new UserServiceImpl();

Będziesz używać tego po wprowadzeniu DI

@Autowired
private UserService userService;

Aby to osiągnąć, musisz utworzyć fasolę swojej usługi w pliku konfiguracyjnym ServiceConfiguration. Następnie należy zaimportować klasę ServiceConfiguration do klasy Webaplicationconfiguration, aby można było Automatycznie uruchomić tę fasolę do kontrolera w ten sposób.

public class AccController {

    @Autowired
    private UserService userService;
} 

Możesz znaleźć Java configuration based POC tutaj przykład

 1
Author: AbdusSalam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-04 02:49:47

Cała koncepcja inwersji sterowania oznacza, że jesteś wolny od obowiązku ręcznego tworzenia instancji obiektów i zapewnienia wszystkich niezbędnych zależności. Gdy dodasz adnotację do klasy za pomocą odpowiedniej adnotacji (np. @Service), Spring automatycznie utworzy dla ciebie instancję obiektu. Jeśli nie jesteś zaznajomiony z adnotacjami, możesz również użyć pliku XML. Jednak nie jest złym pomysłem ręczne tworzenie instancji klas (za pomocą słowa kluczowego new) w testach jednostkowych, gdy nie chcesz ładować całej sprężyny kontekst.

 0
Author: pheasant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-27 10:19:32

Należy pamiętać, że należy włączyć adnotację @Autowired poprzez dodanie elementu <context:annotation-config/> do pliku konfiguracyjnego spring. Spowoduje to zarejestrowanie AutowiredAnnotationBeanPostProcessor, który zajmuje się przetwarzaniem adnotacji.

A następnie możesz automatycznie uruchomić usługę za pomocą metody wtrysku w terenie.

public class YourController{

 @Autowired
 private UserService userService; 

}

Znalazłem to z postu Spring @autowired adnotacja

 0
Author: David Pham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-07 02:08:37