Эти расширение механизма разговора о весне

задняя часть Spring контейнер Dubbo

1. Предпосылки

Будьте осторожны: в этой статье будет много кода.

Глядя на исходный код некоторых фреймворков, можно увидеть, что многие из них будут объединены со Spring. Например, конфигурация dubbo:

Многие люди на самом деле настраивают его, не слишком задумываясь: почему можно распознать spring и запустить dubbo, настроив его таким образом?

Если вам также нужно объединить фреймворк со Spring или вы хотите узнать, как другие фреймворки Spring сочетаются со Spring, вам следует узнать о механизме расширения Spring.

2. Как расширить

Эта статья хочет познакомить, как расширить из двух процессов весны, один является процессом инициализации контейнера, один - процесс создания бобов.

2.1 контейнер инициализации

Чтобы использовать Spring, первым шагом должна быть инициализация контейнера. В AbstractApplicationContext есть метод обновления, который определяет, как обновляется контейнер:

Конкретный процесс обновления выглядит следующим образом:

Среди наиболее распространенных расширений — загрузка BeanDefinition и выполнение BeanPostProcessor. Ниже описано, как расширить эти два.

2.1.1 Загрузка определения компонента

Прежде чем представить загрузку BeanDefinition, давайте сначала разберемся, что такое BeanDefinition.Как следует из названия, BeanDefinition описывает информацию о Bean, такую ​​как информация о его классе, информация об атрибутах, является ли он синглтоном, является ли он отложенной загрузкой и т. д.

Как его загрузить? Обычно есть два способа: один через наш XML, другой через некоторые средства расширения.

xml загружается следующим образом:

Мы настраиваем такое определение bean-компонента в Spring XML, который будет проанализирован и преобразован в наше BeanDefinition.

Другой способ — расширить XML-схему.Подробное введение в xsd см. в этой статье:Механизм расширения схемы XML в Spring. Некоторые студенты спросят, есть ли другой способ аннотации? Когда мы учимся, мы обычно пишем XML и аннотации в книгах, на самом деле аннотации также используют механизм расширения XML-схемы, о нем я расскажу позже.

2.1.1.1 Расширение схемы XML

Какое расширение к XML-схеме?

Spring позволяет вам определить собственную XML-структуру и проанализировать ее с помощью собственного парсера bean-компонентов. Обратитесь сюдаМеханизм расширения схемы XML в Spring4 шага для создания пользовательского расширения:

  • Напишите файл схемы XML, описывающий элементы вашего узла.
    Определите файл demo.xsd в каталоге resources/META-INF/. Здесь определяется элемент демонстрационного узла, который определяет поле имени.
  • Напишите класс реализации NamespaceHandler

  • Напишите одну или несколько реализаций BeanDefinitionParser (критический шаг).

  • Зарегистрируйте вышеуказанную схему и обработчик. Создайте файл spring.handler в каталоге resources/META-INF/ и введите:
http\://www.demo.com/schema/demo = xsd.DemoNameSpaceHandler

, этот шаг сопоставляет URL-адрес нашего предыдущего тега с нашим обработчиком пространства имен. Создайте еще один файл spring.schemas и введите:

http\://www.demo.me/schema/demo/demo.xsd= META-INF/demo.xsd

Этот шаг сопоставляет URL-адрес xsd.

Вернемся к аннотациям. Когда вы настраиваете аннотации, вы обычно используете следующий рисунок для настройки:

Но видно, что он по-прежнему обрабатывается с использованием расширения XML-схемы.В Spring есть ContextNamespaceHandler, который регистрирует множество парсеров:
Одним из парсеров является compnent-scan, который определяет, как сканировать аннотации и получать аннотации в своем методе parse:

С этим механизмом расширения также AOP, MVC, Spring-Cache, а также некоторые из наших сред с открытым исходным кодом, такие как Dubbo и так далее.

2.1.1.2 Расширение BeanFactoryPostProcessor

Этот механизм позволяет нам модифицировать BeanDefinition до фактического создания экземпляра компонента.

Здесь я привожу пример реального боя.Думаю многие из вас настроили пулы соединений с БД.Вот пример Друида:

Затем мы создаем вход druid.properties:

url=jdbc:mysql://localhost:3306/test
username=root
password=123456

Достаточно поиграться с этой конфигурацией, но есть проблема в компании. Пароль хранится в проекте в открытом виде. Это не приемлемо. Пока другие получат разрешение на просмотр вашего проекта, пароль будет утечка, так что общая компания Будет единая служба хранения паролей, которую можно использовать только с достаточными разрешениями, тогда мы можем поместить пароль в единую службу хранения, а пароль можно будет использовать только вызвав службу, то как мы получаем его от удаленной службы Пароль вводится в наш Бин? Затем нам нужно использовать наш BeanFactoryPostpRrocessor, следующий код наследует PropertyPlaceholderConfigurer (класс реализации BeanFactoryPostpRrocessor):

В XML есть:

Таким образом, мы можем получить несколько преимуществ:

  • Настройте единый центр конфигурации, тогда нам не нужно изменять файлы в нашем проекте, нам нужно только изменить его на странице центра конфигурации.
  • Настройте единый центр паролей, тогда нам не нужно выставлять открытый текст в проекте, а как защитить пароль можно напрямую кинуть в центр паролей.

2.2 Создание компонента

Как правило, когда мы получаем bean-компонент в API, мы делаем следующее:

Получено с помощью операции GetBean. Как мы упоминали ранее, если это одноэлементный компонент без ленивой загрузки, он будет загружен при обновлении контейнера. Если это ленивый загруженный компонент, он будет загружен в соответствии с BeanDefinition, когда мы получим Боб. Прежде всего, в AbstractBeanFactory есть два метода: один — doCreate, а другой — create, описывающий, как создать Bean. Вот как создается одноэлементный компонент:

Поток операций doCreateBean выглядит следующим образом:

Вы можете видеть, что настоящая операция создания бина находится в CreateBean.Для реального создания бина есть следующие процессы:

.

2.2.1 Осведомленный интерфейс

Spring предоставляет множество интерфейсов Aware для расширения, с помощью Aware мы можем установить множество вещей, которые хотим установить:

invokeAwareMethod предоставляет три самых основных Aware, если это ApplicationContext, то еще один раунд внедрения Aware выполняется в ApplicationContextAwareProcessor.

  • BeanNameAware: если Spring обнаружит, что текущий объект реализует этот интерфейс, он установит beanName экземпляра объекта в экземпляр денежного объекта.
  • BeanclassLoadRaware: будет загружен ClassLoader, загруженный с текущим компонентом.
  • BeanFactoryAware: внедрить в него текущий контейнер BeanFactory.

Если вы используете контейнер типа ApplicaitonContext, существуют следующие типы:

  • EnvironmentAware: внедрение среды в контексте, который можно использовать при получении свойств конфигурации.

  • EmbeddedValueResolverAware: внедрите EmbeddedValueResolver в контекст, который обычно используется для синтаксического анализа параметров. ResourceLoaderAware: установите в нем контекст.

  • ApplicationEventPublisherAware: реализует интерфейс ApplicationEventPublisher в ApplicationContext, чтобы вы могли внедрить себя в него.

  • MessageSourceAware: внедрить себя.

  • ApplicationContextAware: это то, что мы часто видим, и он внедрит в него свой собственный контейнер.

2.2.2 BeanPostProcessor

Ранее мы сказали BeanFactoryPostProcessor, эти два имени очень похожи, BeanFactoryPostProcessor используется для обработки BeanDefinition в нашей BeanFactory, и Bean в настоящее время не создан. BeanPostProcessor используется для обработки Bean, который мы генерируем.

В BeanPostProcessor есть два метода: один для инициализации предварительной обработки, другой — инициализация для постобработки.

Есть специальный BeanPostProcessor, InstantiationAwareBeanPostProcessor, который реализует этот интерфейс до того, как мы создадим экземпляр процесса, тогда возвращенный им экземпляр объекта будет использован и не войдет в последующий процесс.

Реальный бой: какая польза от BeanPostProcessor?

Если вам необходимо управлять временем выполнения каждого метода в методе проекта, вы можете легко подумать об использовании АОП для этого.Если вам не нужен АОП, вы можете использовать метод постобработки BeanPostProcessor для динамически обрабатывать каждый соответствующий bean-компонент.

2.2.3 InitializingBean/init-method

Spring предоставляет расширение для нашей логики инициализации Bean:

  • Реализуйте интерфейс InitalizingBean:
    В методе afterPropertiesSet() мы можем написать нашу логику инициализации.
  • Через xml-метод:

Наш метод инициализации определен в init-method.

2.2.4 DisposableBean/destory-method

Как говорится, жизнь и смерть никогда не останавливаются. Тогда у нас есть живое расширение, и, естественно, Spring предоставляет мертвое расширение. Мы также можем реализовать нашу логику уничтожения с помощью следующих двух расширений:

  • Одноразовый компонент: Реализовать интерфейс DisposableBean

Просто реализуйте метод уничтожения.

  • Реализовать XML:
    Определите метод уничтожения в методе уничтожения.

PS: В нашем контейнере Spring, если мы хотим автоматически вызывать метод выключения при завершении работы JVM, мы можем ((ClassPathXmlApplicationContext) applicationContext).registerShutdownHook(); зарегистрировать хук выключения, чтобы наши компоненты могли быть безопасно уничтожены, когда JVM выключается.

3. Резюме

В этой статье представлен ряд основных точек расширения из принципа запуска контейнера Spring и принципа инициализации Bean. Конечно, эта часть точки расширения является только частью Spring.Если вам интересно, вы можете прочитать документацию Spring или прочитать исходный код Spring. Если вы сможете освоить эти расширения, вам придется комбинировать эти расширения со Spring, когда вы будете создавать свои собственные колеса в будущем.

Эта статья была включена мной в JGrowing, всеобъемлющий и отличный маршрут изучения Java, совместно созданный сообществом.Если вы хотите участвовать в обслуживании проектов с открытым исходным кодом, вы можете создать его вместе.Адрес github:GitHub.com/Java растет…Пожалуйста, дайте мне маленькую звезду.

Напоследок сделайте рекламу.Если вы считаете, что в этой статье есть статья для вас, то можете обратить внимание на мой технический паблик.За последнее время автор собрал много свежих обучающих материалов,видео и материалов интервью.Вы можете их получить после того, как обратил внимание.Ваше внимание и переадресация-Самая большая поддержка для меня, O(∩_∩)O