1. Обзор
Ядро Spring Framework-это, проще говоря, контейнер IoC, используемый для управления бобами.
В Spring есть два основных типа контейнеров – фабрика бобов и Контекст приложения. Первый обеспечивает основные функциональные возможности, которые представлены здесь ; последний является надмножеством первого и наиболее широко используется.
ApplicationContext – это интерфейс в пакете org.springframework.context , и он имеет несколько реализаций, и ClassPathXmlApplicationContext является одним из них.
В этой статье мы сосредоточимся на полезных функциях, предоставляемых ClassPathXmlApplicationContext .
2. Основное использование
2.1. Инициализация контейнера и управление бобами
ClassPathXmlApplicationContext может загружать конфигурацию XML из пути к классу и управлять ее компонентами:
У нас есть Студент класс:
public class Student { private int no; private String name; // standard constructors, getters and setters }
Мы настраиваем Студент был в classpathxmlapplicationcontext-example.xml и добавьте его в путь к классу:
Теперь мы можем использовать ClassPathXmlApplicationContext для загрузки конфигурации XML и получения компонента Student :
@Test public void testBasicUsage() { ApplicationContext context = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-example.xml"); Student student = (Student) context.getBean("student"); assertThat(student.getNo(), equalTo(15)); assertThat(student.getName(), equalTo("Tom")); Student sameStudent = context.getBean("student", Student.class); assertThat(sameStudent.getNo(), equalTo(15)); assertThat(sameStudent.getName(), equalTo("Tom")); }
2.2. Несколько конфигураций XML
Иногда мы хотим использовать несколько конфигураций XML для инициализации контейнера Spring. В этом случае нам просто нужно добавить несколько местоположений конфигурации при построении ApplicationContext :
ApplicationContext context = new ClassPathXmlApplicationContext("ctx.xml", "ctx2.xml");
3. Дополнительные Возможности
3.1. Изящно Закройте Пружинный контейнер МоК
Когда мы используем контейнер Spring IoC в веб-приложении, веб-реализации Spring ApplicationContext будут корректно завершать работу контейнера при закрытии приложения, но если мы используем его в не веб-среде, такой как автономное настольное приложение, мы должны самостоятельно зарегистрировать крюк завершения работы в JVM, чтобы убедиться, что контейнер Spring IoC корректно завершается и вызывает методы destroy для освобождения ресурсов.
Давайте добавим метод destroy() в класс Student :
public void destroy() { System.out.println("Student(no: " + no + ") is destroyed"); }
Теперь мы можем настроить этот метод как метод уничтожения student bean:
Теперь мы зарегистрируем крюк выключения:
@Test public void testRegisterShutdownHook() { ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-example.xml"); context.registerShutdownHook(); }
Когда мы запускаем метод тестирования, мы видим, что вызывается метод destroy () .
3.2. Интернационализация С Источником Сообщений
Интерфейс ApplicationContext расширяет интерфейс MessageSource , поэтому обеспечивает функциональность интернационализации.
Контейнер ApplicationContext автоматически выполняет поиск компонента MessageSource при его инициализации, и этот компонент должен быть назван как MessageSource .
Вот пример использования разных языков с Источником сообщений :
Во-первых, давайте добавим каталог dialog в путь к классу и добавим два файла в каталог диалога: dialog_en.properties и dialog_zh_CN.properties .
dialog_en.properties :
hello=hello you=you thanks=thank {0}
dialog_zh_CN.properties :
hello=\u4f60\u597d you=\u4f60 thanks=\u8c22\u8c22{0}
Настройте MessageSource bean в classpathxmlapplicationcontext-internationalization.xml :
dialog/dialog
Затем давайте получим диалоговые слова разных языков с помощью MessageSource :
@Test public void testInternationalization() { MessageSource resources = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-internationalization.xml"); String enHello = resources.getMessage( "hello", null, "Default", Locale.ENGLISH); String enYou = resources.getMessage( "you", null, Locale.ENGLISH); String enThanks = resources.getMessage( "thanks", new Object[] { enYou }, Locale.ENGLISH); assertThat(enHello, equalTo("hello")); assertThat(enThanks, equalTo("thank you")); String chHello = resources.getMessage( "hello", null, "Default", Locale.SIMPLIFIED_CHINESE); String chYou = resources.getMessage( "you", null, Locale.SIMPLIFIED_CHINESE); String chThanks = resources.getMessage( "thanks", new Object[] { chYou }, Locale.SIMPLIFIED_CHINESE); assertThat(chHello, equalTo("你好")); assertThat(chThanks, equalTo("谢谢你")); }
4. Ссылка на текст приложения
Иногда нам нужно получить ссылку на ApplicationContext внутри управляемых им компонентов, для этого мы можем использовать ApplicationContextAware или @Autowired . Давайте посмотрим, как работает ApplicationContextAware :
У нас есть Курс класс с именем:
public class Course { private String name; // standard constructors, getters and setters }
У нас есть Учитель класс, который собирает свои курсы в соответствии с фасолью контейнера:
public class Teacher implements ApplicationContextAware { private ApplicationContext context; private Listcourses = new ArrayList<>(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context = applicationContext; } @PostConstruct public void addCourse() { if (context.containsBean("math")) { Course math = context.getBean("math", Course.class); courses.add(math); } if (context.containsBean("physics")) { Course physics = context.getBean("physics", Course.class); courses.add(physics); } } // standard constructors, getters and setters }
Давайте настроим курс боб и учитель был в classpathxmlapplicationcontext-example.xml :
Затем – протестируйте инъекцию курсов свойства:
@Test public void testApplicationContextAware() { ApplicationContext context = new ClassPathXmlApplicationContext( "classpathxmlapplicationcontext-example.xml"); Teacher teacher = context.getBean("teacher", Teacher.class); Listcourses = teacher.getCourses(); assertThat(courses.size(), equalTo(1)); assertThat(courses.get(0).getName(), equalTo("math")); }
Помимо реализации интерфейса ApplicationContextAware , использование аннотации @Autowired имеет тот же эффект.
Давайте изменим класс Учитель на этот:
public class Teacher { @Autowired private ApplicationContext context; private Listcourses = new ArrayList<>(); @PostConstruct public void addCourse() { if (context.containsBean("math")) { Course math = context.getBean("math", Course.class); courses.add(math); } if (context.containsBean("physics")) { Course physics = context.getBean("physics", Course.class); courses.add(physics); } } // standard constructors, getters and setters }
Затем запустите этот тест, и мы увидим, что результат тот же.
5. Заключение
ApplicationContext -это контейнер Spring с более специфичными для предприятия функциями по сравнению с BeanFactory , а ClassPathXmlApplicationContext является одной из его наиболее часто используемых реализаций.
Поэтому в этой статье мы представили несколько аспектов ClassPathXmlApplicationContext , включая его базовое использование , функциональность регистрации завершения работы, функциональность интернационализации и получение ссылки на него.
Как всегда, полный исходный код для примера доступен на GitHub .