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

в 7:11, , рубрики: java, spring framework, Программирование

Добрый день!

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

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

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

Для начала объявим интерфейс, генерирующий стихи srcmainjavaspringinterfacesLyricist.java:

package spring.intarfaces;

public interface Lyricist {
	public String Generate();
}

Реализуем этот интерфейс в классе srcmainjavaspringimplsMayakovsky.java:

package spring.impls;

import spring.intarfaces.Lyricist;

public class Mayakovsky implements Lyricist {

	@Override
	public String Generate() {
		return "А выrn" + "ноктюрн сыгратьrn" + "могли быrn" + "на флейте водосточных труб?";
	}

}

Пропишем, что будем создавать конкретный объект Mayakovsky в конфигурационном xml-файле srcmainresourcesApplicationContext.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. Почти все готово, не хватает только вызывающего класса srcmainjavaspringmainStart.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 srcmainjavaspringimplsPoushkin.java:

package spring.impls;

import spring.intarfaces.Lyricist;

public class Poushkin implements Lyricist {

	@Override
	public String Generate() {
		return "Я помню чудное мгновенье:rn" + "Передо мной явилась ты,rn" + "Как мимолетное виденье,rn"
				+ "Как гений чистой красоты.";
	}

}

Изменим в конфигурационном файле 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-классе. Иногда это удобно.

Добавим специальный настроечный класс srcmainjavaspringmainLyricistConfiguration.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);

В итоге главный файл srcmainjavaspringmainStart.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());

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

Добавим в наш проект простого гражданина, не пишущего стихи srcmainjavaspringimplsSimpleMan.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»

В итоге файл srcmainresourcesApplicationContext.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 и прочие премудрсти.

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

Автор: kvn_2001

Источник


* - обязательные к заполнению поля