Как работает автомастер в Spring?

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

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

Как это будет @Autowired?

И в моем Controllers действии, как бы я instantiate a instance этой службы?

Я бы просто сделал следующее?

UserService userService = new UserServiceImpl();
368
01 июля '10 в 0:26
источник поделиться
9 ответов

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

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

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

Что такое "живое" в контексте приложения? Это означает, что контекст создает объекты, а не вы. То есть - вы никогда не делаете 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 автоувеличивание. В этом случае все поля, которые имеют имя или тип, которые соответствуют существующему bean, автоматически получают bean. Фактически, это была первоначальная идея autowiring - иметь поля, в которые вводились зависимости без какой-либо конфигурации. Могут также использоваться другие аннотации, такие как @Inject, @Resource.
544
01 июля '10 в 0:36
источник

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

Скажем, у вас был beans, определенный в вашем 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, и вводит его автоматически. Если у вас более 1 UserService bean, вам нужно будет определить, какой из них он должен использовать.

Если вы выполните следующее:

UserService service = new UserServiceImpl();

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

54
01 июля '10 в 0:37
источник

@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 instance variables and methods.
    A a;

    private int roll;

    // With setter and getter method

    public void showDetail() {
        System.out.println("Value of id form A class" + a.getId(););
    }
}
15
14 нояб. '14 в 10:31
источник

@Autowired

  • Отмечает конструктор, поле, метод setter или конфигурационный метод, чтобы быть с помощью Spring средств для инъекций зависимостей.

  • Только один конструктор (в макс.) любого заданного класса bean может нести это аннотация, указывающая, что конструктор для автоустановки при использовании в качестве Spring bean. Такой конструктор не должен быть общедоступным.

  • Поля вводятся сразу после построения bean, прежде чем вызывается метод config. Такое поле конфигурации не обязательно должно быть общественности.

  • Способы конфигурации могут иметь произвольное имя и любое количество аргументы; каждый из этих аргументов будет автообновлен с помощью соответствующего bean в контейнере Spring. bean методы настройки свойств фактически просто частный случай такого общего метода конфигурации. такие config не должны быть общедоступными.

  • В случае нескольких методов аргументов параметр 'required' равен применимо для всех аргументов.

  • В случае типа зависимости Collection или Map контейнер будет autowire all beans, соответствующий объявленному типу значения. В случае Карта, ключи должны быть объявлены как тип String и будут разрешены соответствующие имена bean.

6
28 окт. '15 в 12:51
источник

Как @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 внутри?

6
19 дек. '16 в 16:20
источник

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

@Service("userService")

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

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

@Autowired
UserService userService;
3
18 марта '16 в 12:47
источник

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

UserService userService = new UserServiceImpl();

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

@Autowired
private UserService userService;

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

public class AccController {

    @Autowired
    private UserService userService;
} 

Здесь вы можете найти POS-конфигурацию на основе java example

1
04 сент. '17 в 5:28
источник

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

И затем вы можете автоувеличивать свою услугу с помощью метода Field Injection.

public class YourController{

 @Autowired
 private UserService userService; 

}

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

0
07 нояб. '17 в 5:08
источник

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

0
27 июня '17 в 13:19
источник

Посмотрите другие вопросы по меткам или Задайте вопрос