Оригинальный адрес блога:блог Пимайка
предисловие
в предыдущих статьяхАнализ Spring IoC и DIОсновные концепции и взаимосвязи IOC и DI кратко описаны в разделе В общем, IOC — это метод привязки объектов, который может помочь нам разделить зависимости между бизнес-объектами Spring предоставляет два типа контейнеров для поддержки IOC Way. Два типа:
- BeanFactory: базовый тип контейнера IOC, обеспечивающий полную поддержку службы IOC.
- ApplicationContext: ApplicationContext построен на основе BeanFactory и представляет собой относительно продвинутую реализацию контейнера.Помимо всей поддержки BeanFactory, ApplicationContext предоставляет другие расширенные функции.
Отношения наследования между ApplicationContext и BeanFactory следующие:
Вы можете видеть, что ApplicationContext косвенно наследуется от BeanFactory.
BeanFactory
Введение в BeanFactory
BeanFactory — это контейнер IoC базового типа, обеспечивающий полную поддержку службы IoC. Если не указано, по умолчаниюСтратегия ленивой инициализации (ленивая загрузка).Только когда клиентскому объекту требуется доступ к управляемому объекту в контейнере, управляемый объект инициализируется и выполняется работа по внедрению зависимостей..
Регистрация объекта BeanFactory
BeanFactory — это фабрика, которая производит Java Bean.Как базовый контейнер IoC, предоставляемый Spring, BeanFactory помогает завершитьРегистрация бизнес-объектов и привязка зависимостей между объектами.
На самом деле BeanFactory — это просто интерфейс,Он отвечает за определение того, как получить доступ к bean-компонентам, управляемым в контейнере, а конкретный класс реализации каждой BeanFactory отвечает за регистрацию и управление конкретными bean-компонентами.. Ниже приведен код интерфейса BeanFactory:
package org.springframework.beans.factory;
public interface BeanFactory {
/**
* 用来引用一个实例,或把它和工厂产生的Bean区分开,就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory
*/
String FACTORY_BEAN_PREFIX = "&";
/*
* 四个不同形式的getBean方法,获取实例
*/
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
boolean containsBean(String name); // bean是否存在
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 是否为单实例
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 是否为原型(多实例)
boolean isTypeMatch(String name, Class<?> targetType)
throws NoSuchBeanDefinitionException;// 名称、类型是否匹配
Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 获取类型
String[] getAliases(String name);// 根据实例的名字获取实例的别名
}
Давайте протестируем конкретный класс реализации интерфейса BeanFactory в целом:
// 实体类
@Component
public class Demo {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//Junit测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private BeanFactory beanFactory;
@Test
public void test() {
System.out.println("concrete factory is: " + beanFactory.getClass());
Assert.assertTrue("Factory can't be null",beanFactory != null);
Demo demo = (Demo) beanFactory.getBean("demo");
System.out.println("Found the demo bean: "+demo.getClass());
}
}
Результат выглядит следующим образом:
concrete factory is: class org.springframework.beans.factory.support.DefaultListableBeanFactory
Found the demo bean: class com.pjmike.spring.Demo
Из результатов видно, что конкретная фабрикаorg.springframework.beans.factory.support.DefaultListableBeanFactory
пример. посмотри сноваBeanFactory
Наследование отражает:
Как видно из рисунка, BeanFactory управляет тремя подклассами:
- ListableBeanFactory: наследуя этот интерфейс, можно перечислить все bean-компоненты или только bean-компоненты, соответствующие ожидаемому типу.
- HierarchicalBeanFactory: поддерживает управление иерархическими bean-компонентами, позволяя BeanFactory поддерживать функцию управления родительским контейнером IOC.
- AutowireCapableBeanFactory: может заполнять bean-компоненты, не контролируемые Spring
Система подклассов из трех классов - это больше, пожалуйста, обратитесь к исходному коду Spring для получения подробной информации.
Давайте посмотрим на ранее упомянутоеDefaultListableBeanFactory
, который также является классом реализации самого низкого уровня на приведенном выше рисунке:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
...
}
Этот класс на самом делеBeanFactory
Класс реализации по умолчанию более общего класса реализации BeanFactory, который не только косвенно реализует интерфейс BeanFactory, но также реализуетBeanDefinitionRegistryинтерфейс,Этот интерфейс является ролью управления регистрацией Bean в реализации BeanFactory., который абстрактно определяет логику регистрации Bean Конечно, конкретная реализация должна полагаться наDefaultListableBeanFactoryЭто класс реализации.
ApplicationContext
Введение в ApplicationContext
ApplicationContext построен на основе BeanFactory.Да, это относительно продвинутая реализация контейнера.Помимо всей поддержки BeanFactory, ApplicationContext также предоставляет другие расширенные функции, такие как:
- Единая политика загрузки ресурсов
- Международная информационная поддержка
- Механизм публикации внутренних событий контейнера
После запуска контейнера ApplicationContext вся инициализация и привязка завершаются по умолчанию., поэтому для BeanFactory ApplicationContext часто требует больше системных ресурсов
Реализация ApplicationContext
Контекст весной
Spring предоставляет реализацию XmlBeanFactory (унаследованную от DefaultListableBeanFactory) для базового контейнера типа BeanFactory, а также следующие общие реализации для контейнера типа ApplicationContext:
-
org.springframework.context.support.FileSystemXmlApplicationContext
: Реализации ApplicationContext, которые по умолчанию загружают определения bean-компонентов и связанные ресурсы из файловой системы. -
org.springframework.context.support.ClassPathXmlApplicationContext
: по умолчанию реализация ApplicationContext определений компонентов и связанных ресурсов загружается из пути к классам. -
org.springframework.web.context.support.XmlWebApplicationContext
: Предоставленная Spring реализация ApplicationContext для веб-приложений.
В традиционных проектах Spring на основе XML часто используются вышеуказанные классы реализации.
Контекст в Spring Boot
В официальной документации приведена ситуация соответствующего контекста для приложения SpringBoot:
- Для веб-приложений контекст
AnnotationConfigServletWebServerApplicationContext
- Для адаптивных приложений контекст
AnnotationConfigReactiveWebServerApplicationContext
- Для обычных не веб-приложений контекст
AnnotationConfigApplicationContext
Надcontext
На самом деле понялApplicationContext
интерфейс
Простая практика с ApplicationContext
Все мы знаем, что контейнеры IOC обычно имеют два метода внедрения объектов: на основе файла конфигурации XML и на основе аннотаций. Давайте посмотрим, как использовать ApplicationContext с этих двух точек зрения.
Файл конфигурации на основе XML
- определить класс сущности
public class User {
private Integer id;
private String username;
public User(Integer id, String username) {
this.id = id;
this.username = username;
}
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
- Настройте файл конфигурации 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="user" class="com.pjmike.spring.domain.User">
<constructor-arg name="id" value="1"/>
<constructor-arg name="username" value="pjmike"/>
</bean>
</beans>
- основная программа
public class XmlBootStrap {
public static void main(String[] args) {
//构建一个 ApplicationContext 上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
//设置此应用上下文的配置路径
context.setConfigLocations("classpath:/META-INF/spring/context.xml");
//调用 refresh 方法,完成配置的解析、各种BeanFactoryPostProcessor和BeanPostProcessor的注册、国际化配置的初始化、web内置容器的构造
context.refresh();
User user = context.getBean("user", User.class);
System.out.print("user.getName() = "+ user.getUsername());
}
}
выходной результат
user.getName() = pjmike
на основе аннотаций
- объявить класс конфигурации
@Configuration
public class UserConfiguration {
@Bean(name = "user")
public User user() {
User user = new User();
user.setUsername("pj");
return user;
}
}
- основная программа
public class AnnotationBootStrap {
public static void main(String[] args) {
// 构建一个 ApplicationContext 应用上下文
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//注册一个配置 Bean
context.register(UserConfiguration.class);
// 调用 refresh 启动容器
context.refresh();
User user = context.getBean("user", User.class);
System.out.println("user.getName() = "+user.getUsername());
}
}
выходной результат
user.getName() = pj
Простое сравнение XML и Annotation
Из приведенных выше двух примеров видно, что способ внедрения bean-компонентов на основе XML и аннотаций отличается.ClassPathXmlApplicationContext
Путь конфигурации должен быть установлен в зависимости от контекста приложения аннотации.AnnotationConfigApplicationContext
Конфигурационный компонент должен быть зарегистрирован, но тот же шаг для них заключается в том, что они должны быть вызваныrefresh()
метод, этот метод можно рассматривать как метод запуска контейнера IOC, он будет выполнять множество операций, таких как завершение анализа конфигурации, регистрация различных BeanFactoryPostProcessors и BeanPostProcessors, инициализация конфигурации интернационализации, построение веб-встроенного контейнера и т. д., не вызывайте его, контейнер не может запуститься. Это лишь краткое описание, а более подробное введение будет представлено в следующей статье.
Сейчас популярен этап springboot, способ, основанный на файлах конфигурации XML, постепенно заменяется способом, основанным на аннотациях, в современных проектах больше способов использования аннотаций. Более подробное сравнение XML и аннотаций см. в статье Kaitao:Этот год — год Дракона. ITeye.com/blog/187991…
резюме
Вышеприведенная статья кратко суммирует BeanFactory и ApplicationContext, закладывая основу для последующего анализа подробного процесса инициализации Spring IOC и загрузки Spring Beans.