Как работает автопроводка весной?
Я немного смущен тем, как инверсия управления (IoC
) работает в Spring
.
скажем у меня есть класс обслуживания под названием UserServiceImpl
что реализует UserService
интерфейс.
как это будет @Autowired
?
и в моем Controllers
, как бы instantiate
an instance
этой услугой?
Я бы просто сделать следующее?
UserService userService = new UserServiceImpl();
9 ответов:
во - первых, и самое главное - все весенние бобы управляются-они "живут" внутри контейнера, называемого "контекст приложения".
во-вторых, каждое приложение имеет точку входа в этом контексте. Веб-приложения имеют сервлет, JSF использует El-resolver, etc. Кроме того, есть место, где контекст приложения загружается и все бобовые - подгружен. В веб-приложениях это может быть прослушиватель запуска.
Autowiring происходит путем размещения экземпляр одного компонента в нужное поле в экземпляре другого компонента. Оба класса должны быть бобами, т. е. они должны быть определены, чтобы жить в контексте приложения.
что такое "жизнь" в контексте приложения? Это означает, что контекст создает экземпляры объектов, а не вы. То есть-ты никогда не сделаешь
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
аннотация, весна может использовать XML-конфигурируемый autowiring. В этом случае все поля, имеющие имя или тип, совпадающие с существующим компонентом, автоматически получают введенный компонент. Фактически, это была первоначальная идея autowiring - иметь поля, введенные с зависимостями без какой-либо конфигурации. Другие аннотации, такие как@Inject
,@Resource
можно также использовать.
зависит от того, прошли ли вы маршрут аннотаций или маршрут определения XML bean.
скажем, у вас были бобы, определенные в вашем
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, то вам нужно будет определить, какой из них следует использовать.если вы делаете следующее:
UserService service = new UserServiceImpl();
он не будет поднимать @Autowired, если вы не установите его самостоятельно.
@Autowired
является аннотацией, введенной весной 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();); } }
как @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>
если все еще есть некоторые сомнения, то пройдите ниже live demo
@Autowired
отмечает конструктор, поле, метод сеттера или метод конфигурации как быть autowired средствами инъекции зависимости Spring.
только один конструктор (максимум) любого данного класса bean может нести это аннотация, указывающая конструктор для autowire при использовании в качестве Весенняя фасоль. Такой конструктор не обязательно должен быть публичным.
поля вводятся сразу после окончания строительства объекта, перед любым вызываются методы конфигурации. Такое поле конфигурации не обязательно должно быть общественный.
Config методы могут иметь произвольное имя и любое количество аргументы; каждый из этих аргументов будет автоматически подключен с совпадением фасоль в весеннем контейнере. Бобовые методы метода set свойства фактически это просто частный случай такого общего метода конфигурации. Такие методы конфигурации не должны быть публичными.
в случае нескольких аргументов методов, параметр 'required' является применимо для всех аргументов.
в случае типа зависимости коллекции или карты контейнер будет autowire все бобы, соответствующие объявленному типу значения. В случае Map, ключи должны быть объявлены как строка типа и будут разрешены соответствующие имена бобов.
вам просто нужно аннотировать свой класс обслуживания UserServiceImpl с аннотацией
@Service("userService")
контейнер весны позаботится о жизненный цикл этого типа по мере того как он регистрирует как обслуживание.
затем в вашем контроллере вы можете автоматически подключить (создать экземпляр) его и использовать его функциональность.
@Autowired UserService userService;
Spring dependency inject поможет вам удалить соединение из ваших классов. Вместо того, чтобы создавать такой объект
UserService userService = new UserServiceImpl();
вы будете использовать это после введения DI
@Autowired private UserService userService;
для достижения этой цели вам необходимо создать компонент вашего сервиса в файле ServiceConfiguration. После этого вам нужно импортировать этот класс ServiceConfiguration в свой класс WebApplicationConfiguration, чтобы вы могли автоматически подключать этот компонент к своему контроллеру, например этот.
public class AccController { @Autowired private UserService userService; }
вы можете найти конфигурацию java на основе POC здесь пример
вся концепция инверсии управления означает, что вы свободны от рутинной работы по созданию экземпляров объектов вручную и предоставлению всех необходимых зависимостей. Когда вы аннотируете класс с соответствующей аннотацией (например,
@Service
) Spring автоматически создаст экземпляр объекта для вас. Если вы не знакомы с аннотациями, вы также можете использовать XML-файл вместо этого. Тем не менее, это не плохая идея для создания экземпляров классов вручную (сnew
ключевое слово) в модульных тестах, когда вы не хотите загружать весь весенний контекст.
имейте в виду, что вы должны включить аннотацию @Autowired, добавив элемент
<context:annotation-config/>
в файл конфигурации spring. Это зарегистрирует AutowiredAnnotationBeanPostProcessor, который заботится о обработке аннотации.и после этого вы можете autowire ваше обслуживание путем использование метода впрыски поля.
public class YourController{ @Autowired private UserService userService; }
Я нашел это из сообщения Spring @autowired аннотация