Spring IoC, учебное пособие по Spring Bean
Добро пожаловать в учебник по примерам Spring IoC. Spring Framework построен по принципу инверсии управления. Внедрение зависимостей — это метод реализации IoC в приложениях.
Весенний ИОК
- Весна IoC
- Весенняя фасоль
- Области действия Spring Bean
- Конфигурация компонента Spring
- Пример Spring IoC и Spring Bean
- Конфигурация компонента Spring на основе XML
- Конфигурация компонента Spring на основе аннотаций
- Конфигурация Spring Bean на основе Java
Контейнер Spring IoC
Spring IoC — это механизм для достижения слабой связи между зависимостями объектов. Для достижения слабой связи и динамического связывания объектов во время выполнения зависимости объектов внедряются другими объектами ассемблера. Контейнер Spring IoC — это программа, которая внедряет зависимости в объект и делает его готовым для использования. Мы уже рассмотрели, как мы можем использовать Spring Dependency Injection для реализации IoC в наших приложениях. Классы контейнеров Spring IoC являются частью пакетов
org.springframework.beans
иorg.springframework.context
. Контейнер Spring IoC предоставляет нам различные способы разделения зависимостей объектов.BeanFactory
— это корневой интерфейс контейнера Spring IoC.ApplicationContext
— это дочерний интерфейс интерфейсаBeanFactory
, который предоставляет возможности Spring AOP, i18n и т. д. Некоторые из полезных дочерних интерфейсовApplicationContext
— этоConfigurableApplicationContext
иWebApplicationContext
. Spring Framework предоставляет ряд полезных классов реализации ApplicationContext, которые мы можем использовать для получения контекста Spring, а затем Spring Bean. Вот некоторые из полезных реализаций ApplicationContext, которые мы используем;- AnnotationConfigApplicationContext: если мы используем Spring в автономных приложениях Java и используем аннотации для конфигурации, мы можем использовать это для инициализации контейнера и получения объектов bean.
- ClassPathXmlApplicationContext: если у нас есть XML-файл конфигурации bean-компонента Spring в автономном приложении, мы можем использовать этот класс для загрузки файла и получения объекта-контейнера.
- FileSystemXmlApplicationContext: аналогичен ClassPathXmlApplicationContext, за исключением того, что файл конфигурации xml можно загрузить из любой точки файловой системы.
- AnnotationConfigWebApplicationContext и XmlWebApplicationContext для веб-приложений.
Обычно, если вы работаете над приложением Spring MVC и ваше приложение настроено на использование Spring Framework, контейнер Spring IoC инициализируется при запуске приложения, а когда запрашивается bean-компонент, зависимости внедряются автоматически. Однако для автономного приложения вам необходимо инициализировать контейнер где-то в приложении, а затем использовать его для получения компонентов Spring.
Весенняя фасоль
В Spring Bean нет ничего особенного, любой объект в среде Spring, который мы инициализируем через контейнер Spring, называется Spring Bean. Любой нормальный класс Java POJO может быть Spring Bean, если он настроен на инициализацию через контейнер, предоставляя информацию о метаданных конфигурации.
Спринг Бин Сферы
Для Spring Beans определено пять областей.
- singleton — для каждого контейнера будет создан только один экземпляр компонента. Это область действия по умолчанию для spring bean-компонентов. При использовании этой области убедитесь, что у bean-компонента нет общих переменных экземпляра, иначе это может привести к проблемам с несогласованностью данных.
- прототип — новый экземпляр будет создаваться каждый раз, когда запрашивается компонент.
- запрос. Это то же самое, что и область действия прототипа, однако она предназначена для использования в веб-приложениях. Для каждого HTTP-запроса будет создаваться новый экземпляр компонента.
- session — новый компонент будет создаваться контейнером для каждого HTTP-сеанса.
- global-session — используется для создания глобальных сеансовых компонентов для приложений с портлетами.
Spring Framework является расширяемым, и мы также можем создавать свои собственные области видимости. Тем не менее, в большинстве случаев мы хорошо справляемся с областями действия, предоставляемыми фреймворком.
Конфигурация Spring Bean
Spring Framework предоставляет три способа настройки bean-компонентов для использования в приложении.
- Конфигурация на основе аннотаций — с помощью аннотации @Scope.
- Конфигурация на основе XML — путем создания XML-файла конфигурации Spring для настройки bean-компонентов. Если вы используете среду Spring MVC, конфигурацию на основе XML можно загрузить автоматически, написав некоторый шаблонный код в файле web.xml.
- Конфигурация на основе Java. Начиная с Spring 3.0, мы можем настраивать компоненты Spring с помощью программ Java. Некоторые важные аннотации, используемые для конфигурации на основе Java, — это @Bean.
Пример проекта Spring IoC и Spring Bean
Конфигурация Spring Bean на основе XML
MyBean — это простой класс Java POJO.
package com.journaldev.spring.beans; public class MyBean { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
XML-файл конфигурации Spring
код servlet-context.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="https://www.springframework.org/schema/mvc" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:beans="https://www.springframework.org/schema/beans" xmlns:context="https://www.springframework.org/schema/context" xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean> <context:component-scan base-package="com.journaldev.spring" /> <beans:bean name="myBean" class="com.journaldev.spring.beans.MyBean" scope="singleton" ></beans:bean> </beans:beans>
Обратите внимание, что MyBean настраивается с использованием элемента
bean
с областью действия как singleton.Конфигурация Spring Bean на основе аннотаций
package com.journaldev.spring.beans; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import org.springframework.web.context.WebApplicationContext; @Service @Scope(WebApplicationContext.SCOPE_REQUEST) public class MyAnnotatedBean { private int empId; public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } }
MyAnnotatedBean настраивается с помощью @Service, а для области действия задано значение Request.
Класс контроллера Spring IoC
Класс HomeController будет обрабатывать HTTP-запросы для домашней страницы приложения. Мы будем внедрять наши компоненты Spring в этот класс контроллера через контейнер WebApplicationContext.
package com.journaldev.spring.controller; import java.text.DateFormat; import java.util.Date; import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.journaldev.spring.beans.MyAnnotatedBean; import com.journaldev.spring.beans.MyBean; @Controller @Scope("request") public class HomeController { private MyBean myBean; private MyAnnotatedBean myAnnotatedBean; @Autowired public void setMyBean(MyBean myBean) { this.myBean = myBean; } @Autowired public void setMyAnnotatedBean(MyAnnotatedBean obj) { this.myAnnotatedBean = obj; } /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) { System.out.println("MyBean hashcode="+myBean.hashCode()); System.out.println("MyAnnotatedBean hashcode="+myAnnotatedBean.hashCode()); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); model.addAttribute("serverTime", formattedDate ); return "home"; } }
Дескриптор развертывания
Нам нужно настроить наше приложение для Spring Framework, чтобы метаданные конфигурации загружались, а контекст был инициализирован.
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
Почти вся приведенная выше конфигурация представляет собой шаблонный код, сгенерированный инструментом STS автоматически.
Запустите пример приложения Spring IoC Bean
Теперь, когда вы запустите веб-приложение, будет загружена домашняя страница, а в консоли будут напечатаны следующие журналы, когда вы несколько раз обновите страницу.
MyBean hashcode=118267258 MyAnnotatedBean hashcode=1703899856 MyBean hashcode=118267258 MyAnnotatedBean hashcode=1115599742 MyBean hashcode=118267258 MyAnnotatedBean hashcode=516457106
Обратите внимание, что MyBean настроен как одноэлементный, поэтому контейнер всегда возвращает один и тот же экземпляр, а хэш-код всегда один и тот же. Точно так же для каждого запроса создается новый экземпляр MyAnnotatedBean с другим хэш-кодом.
Конфигурация Spring Bean на основе Java
Для автономных приложений мы можем использовать конфигурацию на основе аннотаций, а также на основе XML. Единственное требование — инициализировать контекст где-то в программе, прежде чем мы его используем.
package com.journaldev.spring.main; import java.util.Date; public class MyService { public void log(String msg){ System.out.println(new Date()+"::"+msg); } }
MyService — это простой класс Java с некоторыми методами.
package com.journaldev.spring.main; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(value="com.journaldev.spring.main") public class MyConfiguration { @Bean public MyService getService(){ return new MyService(); } }
Класс конфигурации на основе аннотаций, который будет использоваться для инициализации контейнера Spring.
package com.journaldev.spring.main; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MyMainClass { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( MyConfiguration.class); MyService service = ctx.getBean(MyService.class); service.log("Hi"); MyService newService = ctx.getBean(MyService.class); System.out.println("service hashcode="+service.hashCode()); System.out.println("newService hashcode="+newService.hashCode()); ctx.close(); } }
Простая тестовая программа, в которой мы инициализируем контекст
AnnotationConfigApplicationContext
, а затем используем методgetBean()
для получения экземпляра MyService. Обратите внимание, что я вызываю метод getBean два раза и печатаю хэш-код. Поскольку для MyService не определена область действия, он должен быть одноэлементным, и, следовательно, хэш-код должен быть одинаковым для обоих экземпляров. Когда мы запускаем вышеуказанное приложение, мы получаем следующий вывод консоли, подтверждающий наше понимание.Sat Dec 28 22:49:18 PST 2013::Hi service hashcode=678984726 newService hashcode=678984726
Если вы ищете конфигурацию на основе XML, просто создайте файл конфигурации Spring XML, а затем инициализируйте контекст с помощью следующего фрагмента кода.
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); MyService app = context.getBean(MyService.class);
Это все, что касается руководства по примерам Spring IoC, деталей Spring Bean Scopes и Configuration. Загрузите пример проекта Spring IoC и Spring Bean по ссылке ниже и поэкспериментируйте с ним для лучшего понимания.
Скачать проект Spring Beans
Ссылка: Страница Spring.IO для IOC