Как работает электропроводка весной? - PullRequest
462 голосов
/ 01 июля 2010

Я немного озадачен тем, как инверсия управления (IoC) работает в Spring.

Скажем, у меня есть класс обслуживания с именем UserServiceImpl, который реализует UserService интерфейс.

Как бы это было @Autowired?

А в моем Controllers как бы я instantiate instance этого сервиса?

Буду ли я просто делать следующее?

UserService userService = new UserServiceImpl();

Ответы [ 9 ]

653 голосов
/ 01 июля 2010

Во-первых, и это самое главное - все бины Spring управляются - они «живут» внутри контейнера, называемого «контекстом приложения».

Во-вторых, каждое приложение имеет точку входа в этот контекст.Веб-приложения имеют сервлет, JSF использует el-resolver и т. Д. Кроме того, есть место, где контекст приложения загружается, а все компоненты - автоматически подключаются.В веб-приложениях это может быть прослушиватель запуска.

Автопроводка происходит путем помещения экземпляра одного компонента в нужное поле в экземпляре другого компонента.Оба класса должны быть компонентами, т. Е. Они должны быть определены для жизни в контексте приложения.

Что такое "жизнь" в контексте приложения?Это означает, что context создает объекты, а не вы.Т.е. - вы никогда не делаете new UserServiceImpl() - контейнер находит каждую точку впрыска и устанавливает там экземпляр.

В ваших контроллерах у вас просто есть следующее:

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

    }
}

Несколько замечаний:

  • В вашем applicationContext.xml вы должны включить <context:component-scan>, чтобы классы сканировались на аннотации @Controller, @Service и т. Д.
  • Точка входа дляSpring-MVC-приложение - это DispatcherServlet, но оно скрыто от вас, и, следовательно, прямое взаимодействие и начальная загрузка контекста приложения происходят за сценой.
  • UserServiceImpl также следует определять как bean-компонент - либо с использованием<bean id=".." class=".."> или с использованием аннотации @Service.Поскольку это будет единственный разработчик UserService, он будет внедрен.
  • Помимо аннотации @Autowired, Spring может использовать настраиваемую XML-схему автоматического подключения.В этом случае все поля, которые имеют имя или тип, совпадающий с существующим компонентом, автоматически вводятся в компонент.Фактически, это была первоначальная идея автопроводки - вводить поля с зависимостями без какой-либо конфигурации.Другие аннотации, такие как @Inject, @Resource также могут быть использованы.
61 голосов
/ 01 июля 2010

Зависит от того, прошли ли вы маршрут аннотаций или маршрут определения XML-компонента.

Скажем, у вас есть бобы, определенные в вашем applicationContext.xml:

<beans ...>

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

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

</beans>

Автоматическое подключение происходит при запуске приложения. Итак, в fooController, который ради аргументов хочет использовать класс UserServiceImpl, вы должны аннотировать его следующим образом:

public class FooController {

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

    // rest of class goes here
}

Когда он видит @Autowired, Spring будет искать класс, который соответствует свойству в applicationContext, и вставлять его автоматически. Если у вас более одного компонента UserService, вам нужно будет определить, какой из них следует использовать.

Если вы делаете следующее:

UserService service = new UserServiceImpl();

Он не поднимет @Autowired, если вы не установите его самостоятельно.

17 голосов
/ 14 ноября 2014

@Autowired - это аннотация, появившаяся в Spring 2.5, и она используется только для инъекций.

Например:

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(););
    }
}
9 голосов
/ 19 декабря 2016

Как @Autowired работает внутри?

Ex -

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

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

.xml файл будет выглядеть одинаково, если не использовать @ 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>

Если вы используете @Autowired, тогда

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

.xml файл будет выглядеть одинаково, если не использовать @ Autowired

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

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

Если у вас все еще есть какие-то сомнения, пройдите демонстрацию демо

Как @Autowired работает внутри?

4 голосов
/ 18 марта 2016

Вам просто нужно аннотировать класс обслуживания UserServiceImpl с аннотацией

@Service("userService")

Контейнер Spring позаботится о жизненном цикле этого класса, так как он будет зарегистрирован как сервис.

Затем в вашемконтроллер вы можете автоматически подключить (создать экземпляр) и использовать его функциональность.

@Autowired
UserService userService;
2 голосов
/ 04 сентября 2017

Внедрение зависимостей Spring поможет вам удалить связь с вашими классами.Вместо создания подобного объекта

UserService userService = new UserServiceImpl();

Вы будете использовать его после введения DI

@Autowired
private UserService userService;

. Для этого вам необходимо создать компонент вашего сервиса в файле ServiceConfiguration.После этого вам нужно импортировать этот класс ServiceConfiguration в ваш класс WebApplicationConfiguration, чтобы вы могли автоматически связывать этот bean-компонент с вашим контроллером следующим образом.

public class AccController {

    @Autowired
    private UserService userService;
} 

Вы можете найти POC на основе конфигурации Java здесь example

0 голосов
/ 11 июня 2019

Существует 3 способа создания экземпляра с помощью @ Autowired

Использование @Autowired. После включения добавления аннотаций автоматическое подключение можно использовать для свойств, сеттеров и конструкторов.

3.1.@Autowired для свойств

Аннотация может использоваться непосредственно в свойствах, поэтому устраняется необходимость в методах получения и установки:

@ Компонент Public Class Controller {

@Autowired
UserService userService

}

В приведенном выше примере Spring ищет и вводит fooFormatter при создании FooService.

3.2.@Autowired для сеттеров Аннотация @Autowired может использоваться в методах сеттера.В приведенном ниже примере, когда аннотация используется для метода установки, метод установки вызывается с экземпляром FooFormatter при создании FooService:

открытый класс Controller {

private UserService userService;

@Autowired
public void setUserService(UserService userService) {
        this.userService = userService;
}

}

3.3.@Autowired для конструкторов Аннотация @Autowired также может использоваться для конструкторов.В приведенном ниже примере, когда аннотация используется в конструкторе, экземпляр FooFormatter внедряется в качестве аргумента в конструктор при создании FooService:

открытый класс Controller {

private UserDTO Userdto;

@Autowired
public UserService(UserDTO userDTO) {
    this.userDTO = userDTO;
}

}

Надеюсь, это поможет вам.

0 голосов
/ 07 ноября 2017

Помните, что вы должны включить аннотацию @Autowired, добавив элемент <context:annotation-config/> в файл конфигурации пружины.Это зарегистрирует AutowiredAnnotationBeanPostProcessor, который заботится об обработке аннотаций.

А затем вы можете автоматически подключить свой сервис, используя метод Field Injection.

public class YourController{

 @Autowired
 private UserService userService; 

}

Я нашел это из сообщения Spring @autowired аннотация

0 голосов
/ 27 июня 2017

Вся концепция инверсии управления означает, что вы свободны от рутинной работы по созданию экземпляров объектов вручную и предоставлению всех необходимых зависимостей. Когда вы аннотируете класс соответствующей аннотацией (например, @Service), Spring автоматически создаст экземпляр объекта для вас. Если вы не знакомы с аннотациями, вы также можете использовать XML-файл. Однако неплохо было бы создавать экземпляры классов вручную (с ключевым словом new) в модульных тестах, когда вы не хотите загружать весь контекст пружины.

...