Когда дело доходит до весны, я должен упомянуть ее две основные функции, IOC и АОП. В этой статье в основном представлены связанные принципы весеннего ввода-вывода в сочетании с кодом. Если читать исходный код только для того, чтобы увидеть исходный код, эффективность будет быть очень низким, и он должен иметь определенную цель Следующие вопросы можно найти в исходном коде. Эта статья"Академия Тьюринга"Примечания к курсу
- Как Bean Factory производит бобы
- Bean-зависимости разрешены тем, кто
- Разница между Bean Factory и контекстом приложения
Как видно из общей схемы архитектуры Spring Ioc на следующем рисунке, Spring считывает информацию о конфигурации bean-компонента при запуске и генерирует соответствующий реестр конфигурации bean-компонента в spring, а затем создает экземпляр bean-компонента в соответствии с реестром и собирает bean-компоненты между ними.Зависимости, предоставляют экземпляры bean-компонентов для приложений верхнего уровня, в которых пул кэширования bean-компонентов реализуется через hashmap
процесс построения фасоли
Spring.xml сохраняет описание и конфигурацию бинов.BeanFactory считывает эти конфигурации и затем генерирует бины.Это наше общее понимание принципа ioc.Если подумать дальше, то проблем будет больше.
- Какой объект Java несет содержимое информации о конфигурации
- Эти объекты-носители считываются из файла конфигурации и загружаются
- Где хранятся эти загруженные объекты?
BeanDefinition
В реализации ioc информация Bean, описанная в xml, будет окончательно сохранена в объекте BeanDefinition (определение), в котором bean-компонент xml имеет отношение один к одному с процессом BeanDefinition. Свойства, установленные в xml bean-компоненте, наконец, будут отражены в BeanDefinition.
Можно видеть, что атрибуты, установленные в xml bean-компоненте, в конечном итоге будут отражены в BeanDefinition. Такие как:
**XML-bean ** | BeanDefinition |
---|---|
class | beanClassName |
scope | scope |
lazy-init | lazyInit |
constructor-arg | ConstructorArgument |
property | MutablePropertyValues |
factory-method | factoryMethodName |
destroy-method | AbstractBeanDefinition.destroyMethodName |
init-method | AbstractBeanDefinition.initMethodName |
autowire | AbstractBeanDefinition.autowireMode |
id | |
name |
Структура свойства BeanDefinition
BeanDefinitionRegistry (реестр компонентов)
В приведенной выше таблице мы не видим, что атрибуты id и name в xml bean-компоненте не отражены в определении, потому что ID зарегистрирован в BeanDefinitionRegistry как ключ хранения текущего bean-компонента. name регистрируется в реестре AliasRegistry как ключ псевдонима. Наконец, он указывает на соответствующее BeanDefinition.
Структура свойства BeanDefinitionRegistry
BeanDefinitionReader (считыватель определений компонентов)
Теперь мы понимаем, что информация Xml Bean хранится в BeanDefinition, а BeanDefinitionRegister сохраняет определения Bean на основе идентификатора и имени. Следующее, что нужно изучить, это весь процесс от xml Bean до BeanDefinition, а затем регистрация в BeanDefinitionRegister.
Как видно из рисунка выше, определение bean-компонента считывается конфигурацией из xml с помощью BeanDefinitionReader и создает BeanDefinitionReader, а затем регистрируется в BeanDefinitionRegister на основе псевдонима.
Структура BeanDefinitionReader
- int loadBeanDefinitions(Resource var1)
Загрузите beanDefinition на основе ресурса и зарегистрируйтесь в регистраторе
-
int loadBeanDefinitions(String var1)
Загрузите beanDefinition на основе пути к ресурсу и зарегистрируйте регистратор большого экрана.
-
BeanDefinitionRegistry getRegistry()
получить регистратора
-
ResourceLoader getResourceLoader()
получить загрузчик ресурсов
Демонстрирует процесс загрузки BeanDefinitionReader на примере
//创建一个简单注册器
BeanDefinitionRegistry register = new SimpleBeanDefinitionRegistry();
//创建bean定义读取器
BeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
// 创建资源读取器
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
// 获取资源
Resource xmlResource = resourceLoader.getResource("spring.xml");
// 装载Bean的定义
reader.loadBeanDefinitions(xmlResource);
// 打印构建的Bean 名称
System.out.println(Arrays.toString(register.getBeanDefinitionNames());
Beanfactory (бобовая фабрика)
Наличие определения фасоли эквивалентно владению формулой продукта, и следующим шагом является отправка формулы на фабрику для производства. Конструкцией Bean-компонентов в ioc занимается BeanFactory. Его структура выглядит следующим образом:
Описание метода:
- getBean(String)
- Получить Bean на основе идентификатора или имени
- T getBean(Class requiredType)
- Получить bean-компонент на основе класса bean-компонента (если есть несколько экземпляров этого класса, будет сообщено об ошибке. Но вы можете указать primary="true", чтобы настроить приоритет для устранения ошибки)
- Object getBean(String name, Object... args)
- Получить bean-компонент на основе его имени и переопределить параметры построения по умолчанию
- boolean isTypeMatch(String name, Class<?> typeToMatch)
- Соответствует ли указанный компонент указанному классу
В приведенных выше методах фокус должен быть на getBean.Когда пользователь вызывает getBean, будет запущено действие создания bean-компонента.Как он создается?
Продемонстрируйте базовую фабрику BeanFactory, чтобы получить компонент
#创建Bean堆栈
// 其反射实例化Bean
java.lang.reflect.Constructor.newInstance(Unknown Source:-1)
BeanUtils.instantiateClass()
//基于实例化策略 实例化Bean
SimpleInstantiationStrategy.instantiate()
AbstractAutowireCapableBeanFactory.instantiateBean()
// 执行Bean的实例化方法
AbstractAutowireCapableBeanFactory.createBeanInstance()
AbstractAutowireCapableBeanFactory.doCreateBean()
// 执行Bean的创建
AbstractAutowireCapableBeanFactory.createBean()
// 缓存中没有,调用指定Bean工厂创建Bean
AbstractBeanFactory$1.getObject()
// 从单例注册中心获取Bean缓存
DefaultSingletonBeanRegistry.getSingleton()
AbstractBeanFactory.doGetBean()
// 获取Bean
AbstractBeanFactory.getBean()
// 调用的客户类
com.tuling.spring.BeanFactoryExample.main()
Схема последовательности создания бина:
Из процесса вызова можно сделать следующие выводы:
- Вызов BeanFactory.getBean() запускает создание экземпляра компонента.
- Компоненты Singleton кэшируются в DefaultSingletonBeanRegistry.
- Создание и инициализация компонента выполняется с помощью AbstractAutowireCapableBeanFactory.
Разница между BeanFactory и ApplicationContext
Кажется, что BeanFactory может делать большинство вещей в IOC, так зачем определять ApplicationContext? Диаграмма структуры ApplicationContext
Как видно из рисунка, ApplicationContext является производным от интерфейса BeanFactory, обеспечивая тем самым все функции BeanFactory. Кроме того, контекстный пакет также предоставляет следующие функции:
- MessageSource, обеспечивающий интернационализированный доступ к сообщениям.
- Доступ к ресурсам, таким как URL-адреса и файлы
- Распространение событий, компонент, реализующий интерфейс ApplicationListener.
- Загружать несколько (унаследованных) контекстов, чтобы каждый контекст фокусировался на определенном уровне, например веб-слое приложения.
исходный адрес