Как я изучаю фреймворк Spring (помощь начинающим — дело рук самих начинающих)

от автора

Добрый день!

Я поставил себе цель изучить фреймфорк Spring для языка Java. Во время изучения решил проверить на себе алгоритм обучения Ричарда Фейнмана: организовать-упростить-обучить другого. В общем, я стал записывать серию коротких уроков для начинающих по работе в Spring. Для желающих повторить выложил исходный код.

Урок 01. Разбираемся с IoC

Итак, соберем вместе поэтов, пускай сочиняют и читают нам свои стихи.

Для начала объявим интерфейс, генерирующий стихи src\main\java\spring\interfaces\Lyricist.java:

package spring.intarfaces;  public interface Lyricist { 	public String Generate(); } 

Реализуем этот интерфейс в классе src\main\java\spring\impls\Mayakovsky.java:

package spring.impls;  import spring.intarfaces.Lyricist;  public class Mayakovsky implements Lyricist {  	@Override 	public String Generate() { 		return "А вы\r\n" + "ноктюрн сыграть\r\n" + "могли бы\r\n" + "на флейте водосточных труб?"; 	}  } 

Пропишем, что будем создавать конкретный объект Mayakovsky в конфигурационном xml-файле src\main\resources\ApplicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  	<bean id="LyricistBean1" class="spring.impls.Mayakovsky"/> </beans> 

Связали id LyricistBean1 c именем класса Mayakovsky. Почти все готово, не хватает только вызывающего класса src\main\java\spring\main\Start.java:

package spring.main;  import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;  import spring.intarfaces.Lyricist;  public class Start {  	public static void main(String[] args) { 		ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); 		Lyricist lyr1 = context.getBean("LyricistBean1", Lyricist.class); 		System.out.println(lyr1.Generate());  		((ConfigurableApplicationContext) context).close();// закрытие контекста вручную  	}  } 

В классе Start мы прочитали наш конфигурационный файл, создали экземпляр поэта по имени бина LyricistBean1. Получили экземпляр поэта Mayakovsky. Функция Generate() вернула нам бессмертные строки:

А вы
ноктюрн сыграть
могли бы
на флейте водосточных труб?

Урок 02. Выбор создаваемого экземпляра через конфигурационный файл

Допустим, друг помог нам и предоставил другую реализацию нашего интерфейса Lyricist src\main\java\spring\impls\Poushkin.java:

package spring.impls;  import spring.intarfaces.Lyricist;  public class Poushkin implements Lyricist {  	@Override 	public String Generate() { 		return "Я помню чудное мгновенье:\r\n" + "Передо мной явилась ты,\r\n" + "Как мимолетное виденье,\r\n" 				+ "Как гений чистой красоты."; 	}  } 

Изменим в конфигурационном файле ApplicationContext.xml слово Mayakovsky на слово Poushkin.

Запускаем программу. Получаем без пересборки совсем другой результат:

Я помню чудное мгновенье
Передо мной явилась ты,
Как мимолетное виденье,
Как гений чистой красоты.

Урок 03. Бины в коде, а не в конфигурационном файле

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

Изменим класс Poushkin.java

  1. Добавим импорт библиотеки import org.springframework.stereotype.Component;
  2. Поставим аннотацию Component(«LyricistBean1») перед объявлением класса

Таким образом мы намекнули Spring, что хотим в виде первого поэта видеть именно Poushkin, а никак не кого-то другого.

Осталось чуть-чуть исправить конфигурационный файл ApplicationContext.xml:

1. Добавим сверху пространство имен context: xmlns:context=«www.springframework.org/schema/context»;

2. Удалим ненужную строку: />

3. Добавим вместо нее команду автоматически добавлять в программу бины из всех классов, расположенных в каталоге spring.impls:

<context:component-scan base-package=«spring.impls»/>

В итоге файл ApplicationContext.xml должен выглядеть вот так:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 	xmlns:context="http://www.springframework.org/schema/context" 	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">  	<context:component-scan base-package="spring.impls"/>	  </beans> 

Запускаем. Получаем тот же результат, что и в предыдущем уроке.

Урок 04. Конфигурационный класс

Избавимся совсем от xml-файла.

Все настройки могут находиться и в java-классе. Иногда это удобно.

Добавим специальный настроечный класс src\main\java\spring\main\LyricistConfiguration.java в нашу программу:

package spring.main;  import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;  @ComponentScan(basePackages = { "spring.impls" }) @Configuration public class LyricistConfiguration {  } 

@ComponentScan показывает, в каком каталоге искать бины.
@Configuration сообщает, что наш класс специальный, конфигурационный.

Все, xml-файл больше не нужен. Осталось сообщить эту новость нашему основному классу:

  1. Дополним его нужным импортом import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  2. Заменим строку создания контекста
    ApplicationContext context = new AnnotationConfigApplicationContext(LyricistConfiguration.class);

В итоге главный файл src\main\java\spring\main\Start.java должен выглядеть вот так:

package spring.main;  import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;  import spring.intarfaces.Lyricist;  public class Start {  	public static void main(String[] args) { 		ApplicationContext context = new AnnotationConfigApplicationContext(LyricistConfiguration.class); 		Lyricist lyr1 = context.getBean("LyricistBean1", Lyricist.class); 		System.out.println(lyr1.Generate());  		((ConfigurableApplicationContext) context).close();// закрытие контекста вручную  	}  } 

Все запускается и по-прежнему выдает бессмертные Пушкинские строки. Все работает. Но уже без xml.

Урок 05. Singleton и Prototype

Исследуем возможности конфигурационного файла. Поэтому вернемся пока к проекту из второго урока. Попробуем в Start.java создать два экземпляра класса Poushkin и удостоверимся, что великий поэт один и тот же:

	Lyricist lyr1 = context.getBean("LyricistBean1", Lyricist.class); 	System.out.println(lyr1.Generate()); 	System.out.println(lyr1.hashCode());  	Lyricist lyr2 = context.getBean("LyricistBean1", Lyricist.class); 	System.out.println(lyr2.Generate()); 	System.out.println(lyr2.hashCode()); 

И стихи одни и те же, и хэш-код сорпадает. Все в порядке.

Добавим в наш проект простого гражданина, не пишущего стихи src\main\java\spring\impls\SimpleMan.java:

package spring.impls;  import spring.intarfaces.Lyricist;  public class SimpleMan implements Lyricist {  	@Override 	public String Generate() { 		return "Я человек простой, стихов не пишу"; 	}  } 

Зарегистрируем класс в конфигурационном файле (сразу после первого бина)

 <bean id="LyricistBean2" class="spring.impls.SimpleMan"/>

Пробуем создать

	Lyricist lyr1 = context.getBean("LyricistBean2", Lyricist.class); 	System.out.println(lyr1.Generate()); 	System.out.println(lyr1.hashCode());  	Lyricist lyr2 = context.getBean("LyricistBean2", Lyricist.class); 	System.out.println(lyr2.Generate()); 	System.out.println(lyr2.hashCode()); 

Гражданин все время один и тот же. Непорядок…

Изменим регистрацию бина в конфигурационном файле, добавив волшебное слово scope=«prototype»

В итоге файл src\main\resources\ApplicationContext.xml будет выглядеть так:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  	<bean id="LyricistBean1" class="spring.impls.Poushkin" scope="singleton"/> 	<bean id="LyricistBean2" class="spring.impls.SimpleMan" scope="prototype"/>  </beans> 

Теперь все в порядке. Граждане каждый раз разные. А Пушкин всегда один.

Внимательные заметили, что в первом бине добавилась настройка scope=«singleton», но это настройка используется по умолчанию, поэтому ее можно и не писать.

На сегодня все. Если данный пост пройдет премодерацию, а у меня появятся время и силы, будет продолжение про AOP, JDBC, транзакции, MVC и прочие премудрсти.

С уважением, Владимир


ссылка на оригинал статьи https://habr.com/post/420901/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *