В классе Java великий человек по имени Род Джонсон обнаружил, что первоначальная разработка на уровне предприятий Java была в хаотическом состоянии.
Поэтому он решил написать общую инфраструктуру, которая может решить проблемы.
Потому что он твердо верит, что программирование, ориентированное на интерфейс, может минимизировать изменения, но также способствовать расширению и изменениям. Итак, он написал следующий интерфейс.
Первое, что нужно создать в хаотическом состоянии, - это мать всех объектов, Beanfactory, и вместе с ним вы можете получить все объекты и атрибуты, которые он воспитывает, то есть, прежде всего, Гайя - мать Земли.
Джонсон подумал, что с оригинальной Mother Beanfactory, что, если я хочу получить набор объектов бобов вместо одного или нескольких? Кроме того, что, если ребенок матери также хочет родить партнера? Таким образом, Джонсон создал SirefbleBeanFactory для управления набором объектов бобов. Например, GetBeansOftype может получить набор бобов того же типа на основе его; Созданный иерархический Bainfactory для решения иерархических задач множественного BeanFactory, таких как GetParentBeanFactory, может получить родительскую фабрику BeanFactory.
Этот BeanFactory в конечном итоге используется в приложении, поэтому BeanFactory должна быть предоставлена возможность двигаться в приложении. В Beanfactory вам нужно только рассмотреть поведение, связанное с бобами, например, как получить бобы, тип бобов и т. Д.; И если вы хотите дать им способности в приложении, вам необходимо учитывать больше, например, имя приложения, время запуска, идентификатор и т. Д. Джонсон подумал, что этот приложений должен быть в состоянии делать много вещей, и он должен иметь возможность обрабатывать параметризованную и интернационализированную текстовую информацию, поэтому он добавляет интерфейс MessageSource; Он должен быть в состоянии публиковать события для отделки компонентов, поэтому он имеет интерфейс ApplicationEventPublisher; Он должен быть в состоянии получить файлы ресурсов, поэтому он имеет интерфейс ресурсов; Он должен быть в состоянии иметь разные объекты обработки в разных средах, поэтому он имеет экологичный интерфейс.
ApplicationContext наследует все эти интерфейсы.
Но самое главное, что как BeanFactory, так и ApplicationContext должны иметь настраиваемые возможности, поэтому существуют суб-интерфейсы, настраиваемые beanfactory и configuruRableApplicationContext; Кроме того, сеть была очень важной тенденцией в то время, и она была немного уникальной по сравнению с другими приложениями, поэтому ей нужно было получить ServletContext, поэтому был WebApplicationContext.
До сих пор Джонсон был абстрактным, думая о поведении интерфейса и не внедрил их подробно.
Глядя на созданный Beanfactory и ApplicationContext, Джонсон понял, что работа дня была далеко не завершена, потому что не было реального решения, чтобы заставить всю систему работать, поэтому Джонсон начал думать о том, как их реализовать.
Первое, о чем думает Джогосон, это то, какие возможности должны иметь эта реализация? Конечно, нам нужно включить AutoWireCapableBeanFactory, SireftableBeanfactory и конфигурируется, упомянутое ранее. Поэтому был создан конфигурационная корреспонденция. Во -вторых, необходимо учитывать несколько способностей для объектов бобов, один из них - способность к псевдониванию; Второе - это способность сохранять односпособные объекты; Третий - это способность кешю; Они реализованы в классе SimplealiasRegistry, классе по умолчанию, классу по умолчанию и классу FactoryBeanRegistryPorsPort соответственно.
Наконец, был создан DefaultBeanbeanFactory, который является прототипом всех заводов МОК весной и является первым настоящим ребенком BeanFactory. Этот ребенок очень важен и стал основой для независимого создания контейнеров МОК. Если он расширен и используется, большинство из них унаследованы или используются в комбинации.
Если вы хотите инициализировать по умолчанию списково -обеспеченное значение, вы можете использовать следующий код
ClassPathresource res = new ClassPathresource ("ApplicationContext.xml"); Default -letrablebeanfactory f = new DefaultStableBeanFactory (); XmlbeandefinitionReader r = new XmlBeanDefinitionReader (f); R.LoadBeanDefinitions (RES); Затем Джонсон подумал, что BeanFactory имеет относительно всеобъемлющую реализацию по умолчанию, так что насчет ApplicationContext? Таким образом, Джонсон неутомимо создал три важных реализации ApplicationContext: FileSystemXmlapplicationContext, ClassPathxMlapplicationContext, AnnotationConfigWebApplicationContext (на самом деле, есть еще много, например, обработка порт и обработку веб -сайтов)
Первое, что Джонсон считает, это как сделать процесс весеннего запуска. Он должен быть помещен в относительно абстрактный уровень, чтобы все классы на нижнем уровне могли быть использованы повторно. Таким образом, он реализовал ConfiguruRableApplicationContext, используя AbstractApplicationContext. Существует также очень важная функция, то есть загрузка файла в форме ресурса, которая требует абстрагирования ресурса в класс ресурсов и абстрагировать конкретную реализацию ресурса позиционирования ресурсу. AbstractApplicationContext также должен унаследовать Defaultresourceloader, чтобы обеспечить эту функцию. AbstractApplicationContext завершил весь процесс запуска (Бог организовал его на следующий день), но он не управлял BeanFactory. Таким образом, его подкласс AbstractrefreshableaPplicationContext делает это конкретно, реализуя обновления, теснофункциональный, GetBeanFactory, в частности, управляет жизненным циклом BeanFactory, но AbstractRefreshableApplicationContext по -прежнему не загружает все настроенные бобы. Где загрузить настроенные ресурсы, он фактически переходит к нижнему подклассу, чтобы сделать это, например, файловой системы. ClassPathxmlapplicationContext - это прочитать этот приложение Context в путь загрузки класса. AnnotationConfigWebApplicationContext загружает бобы из аннотации файла класса, и Spring Scanning начинается с этого момента.
Видя, что основной кадр была установлена, Джонсон заснул с удовлетворением улыбкой.
В первый день Джонсон завершил весеннюю общую структуру.
На второй день Джонсон готовился решать предыдущие проблемы. Например, процесс инициализации контейнера пружины. Как показано на рисунке, Джонсон делит этот процесс на многие подпроцессы, которые работают вокруг великой цели загрузки бобов.
Этот процесс помещается в метод обновления в AbstractApplicationContext. Код выглядит следующим образом: Джонсон делит процесс обновления на многие подпроцессы, и эти подпроцессы находятся на одном и том же абстрактном уровне. Этот способ письма - дать будущим поколениям образец для подражания.
public void refresh () бросает Beansexception, allodalStateException {synchronized (this.startupshutdownmonitor) {// Подготовка этого контекста для освежения. PrepareRefresh (); // Скажите подклассу обновлять фабрику внутренних бобов. Configurablelistablebeanfactory beanfactory = effershbeanfactory (); // Подготовьте фабрику бобов для использования в этом контексте. PrepareBeanFactory (BeanFactory); Попробуйте {// Позволяет после обработки фабрики бобов в подклассах контекста. PostProcessBeanFactory (BeanFactory); // вызывают заводские процессоры, зарегистрированные как бобы в контексте. InvokebeanfactoryPostProcessors (BeanFactory); // Зарегистрировать процессоры бобов, которые перехватывают создание бобов. Registerbeanpostprocessors (Beanfactory); // Инициализировать источник сообщения для этого контекста. initmessagesource (); // Инициализировать событие Multicaster для этого контекста. initApplicationEventMulticaster (); // Инициализировать другие специальные бобы в конкретных подклассах контекста. OnRefresh (); // Проверьте на наличие бобов слушателя и зарегистрируйте их. RegistralListeners (); // создание всех оставшихся (не-ленивых) синглтонов. FinishBeanfactoryinialization (BeanFactory); // Последний шаг: опубликовать соответствующее событие. finishRefresh (); } catch (beansexception ex) {// уничтожить уже созданные синглетоны, чтобы избежать висящих ресурсов. DestroyBeans (); // сбросить 'Active' Flag. CancelRefresh (Ex); // распространять исключение на вызывающего абонента. бросить бывш; }}} Если вы посмотрите на это на более высоком уровне, эти процессы фактически вращаются вокруг нескольких аспектов: 1. Обновить жизненный цикл; 2. Инициализация и подготовка BeanFactory; 3. генерировать и зарегистрировать Beaindefinition; 4. Beanfactory Postprocessor; 5. Установите сообщения, события и слушатели.
1. Освежающий жизненный цикл
PrepareRefresh, этот процесс в основном записывает журнал и указывает на то, что Spring началась, инициализирует ресурсы недвижимости (например, инициализацию некоторых ресурсов в Серлвете) и проверка ресурсов собственности (например, только написание ключа без значения).
OnRefresh цель состоит в том, чтобы предоставить некоторые специальные приложения, чтобы они могли расширяться в процессе обновления. Большая часть текущего использования - установить тему для контекста приложения Сервлета
FinishRefresh, выполняйте некоторые отдельные работы, такие как инициализация жизненного цикла, публикация событий, заканчивающихся обновлением и т. Д.
CancelRefresh, в основном изменяет текущее состояние на неактивное, когда происходит исключение.
2. Инициализация и подготовка BeanFactory
Джонсон думает, что мы должны позволить BeanFactory нагрузку и прозрачно зарегистрировать бобы при инициативе, поэтому моя инкапсуляция очень успешна для внешнего мира, поэтому этот шаг фактически делает много вещей. На следующем рисунке пропускается много шагов и перечисляет только ключевые точки.
AbstractApplicationContext будет называть обновления. Сначала он проверит и закроет существующий BeanFactory, затем создаст новый BeanFactory, а затем использует эту фабрику для загрузки всех боандж.
Среди них Loadbeandefinitions будут переданы подклассам для различных реализаций. Например, AbstractxmlApplicationContext в основном читается через XML; Аннотацияконфигвебаппликационная реализация позвонит сканеру для сканирования бобов в классе.
3. Сгенерировать и зарегистрировать Beandefinition
После анализа конфигурации XML метод ParsedeFaultElement of DefaultBeandefinitionDocumentReader будет выполнять соответствующую обработку на основе элементов в XML. Среди них, когда встречается с элементом бобов, наконец будет вызван метод регистрации в BeandefinitionReadRutils. Параметр, переданным в этом методе, является BeandefinitionRegistry, который фактически вызывает метод регистрации Beanbeandefinition метода DefaultStableBeanfactory для регистрации Beandefinition (Default -stistablebeanfactory реализует BeandefinitionRegistry).
4. Beanfactory Postprocessor
Beanfactory Postprocessor - это способ, который будет предоставлен, чтобы позволить его подклассам быть гибкими. Весной есть 2 шага: PostProcessBeanFactory, InvokeBeanFactoryPostProcessors. Registerbeanpostprocessors создания экземпляра и вызов всех Beanpostprocessors, которые используются для расширения бобов до и после инициализации бобов.
5. Настройка сообщений, событий и слушателей
Установите источник сообщения по умолчанию в делегирование Messagesource. Если на фабрике уже есть сообщения о сообщении, используйте этот сообщений. Multicaster Event SimpleApplicationEventMulticaster. Если на заводе уже есть ApplicationEventMulticaster, используйте это ApplicationEventMulticaster и зарегистрируйте всех слушателей приложений для получения событий.
MessageSource является важным методом для международных файлов ресурсов. Spring поддерживает источники сообщений в ApplicationContext.
Spring обеспечивает реализацию сообщений Speakyource по умолчанию, используя java.util.resourcebundle для извлечения сообщений. Spring может непосредственно получить доступ к сообщению от ApplicationContext.getMessage (), настраивая компонент со специальным идентификатором в качестве MessageSource и установив имя файла i18n. Если в JSP, вы также можете получить доступ к сообщению через тег Spring: сообщения.
Событие: События являются относительно важным механизмом развязки. Spring представила его в Core ApplicationContext. Его принцип относительно прост. С одной стороны, генератор событий может отправлять события; С другой стороны, кажется, что слушатель событий может ответить на события. Конкретная реализация в основном содержит коллекцию слушателей событий в генераторе и «Зарегистрироваться» (то есть присоединение) - все слушатели в этой коллекции слушателей событий.
Весной, в качестве генератора событий используется ApplicationContext, используется в качестве коллекции слушателей, а ApplicationEventMulticaster используется для публикации событий.
Несколько шагов по публикации события:
Подписка: первоначально AddapplicationListener в коллекцию слушателей.
Publish: ApplicationContext наследует ApplicationEventPublisher, внедряя, таким образом, PublishEvent. Этот метод сначала пройдет коллекцию ApplicationListeners этого ApplicationContext, Call OnaPplicationEvent для каждого слушателя, поэтому каждый прослушиватель будет уведомлен; После того, как этот шаг будет выполнен, то же событие будет опубликовано для всех приложений, которые стали родителями ApplicationContext.
Публикация событий очень распространена. Не только наши собственные приложения могут использовать это публикацию этого события, но сама Spring Framework также использует публикацию событий. Вот некоторые приложения событий весной:
Contextrefreshedevent будет опубликовано в FinishRefresh, чтобы указать, что обновление заканчивается и уведомляет слушателя. В ApplicationContext методы начала и остановки будут публиковать события, которые указывают на начало или конец контекста.
После того, как Джонсон создал основную структуру и процесс работы весны, он обнаружил, что Spring предоставляет много гибких мест расширения. Таким образом, Джонсон готовится объявить об этом гибком использовании расширения на третий день.
1. Beanpostprocessor. BeanpostProcessor обеспечивает интерфейс расширения после завершения создания бобов. Когда вам нужно сделать некоторую обработку на бобах после их создания, Beanpostprocessor является предпочтительным методом.
2. Инъецированное бобое должно знать некоторые части своего контейнера. Spring завершает обратные вызовы через Able, такие как Beannameaware, что позволяет бобам знать свое название. BeanFactoryAware может позволить бобам понять BeanFactory, ApplicationContextAware, который позволяет бобам использовать ApplicationContext. Таким образом, боб, вводящий пружину, может сделать более широкий спектр вещей.
Для расширения Beanpostprocessor, сама Spring имеет пример того, как определить осведомленную фасоль. Осознанные бобы являются относительно особыми бобами, а пружина требует некоторых дополнительных атрибутов. Итак, как будет использоваться пружина для процесса впрыска? Фактически, Spring не пишет его в основном процессе обработки, но помещайте в ApplicationContextAwareProcessor, BeanpostProcessor и, наконец, InvokeaReainaterfaces, чтобы определить тип бобов и соответствующих атрибутов. Этот подход использует Beanpostprocessor для завершения другого расширенного использования, что действительно великолепно.
private void invokeawareInterfaces (Object Bean) {if (exaturefeaf ancementof) {if (exancefulf EnvironmentaOf) {((EnvironmentAware) Bean) .setEnvironment (this.ApplicationContext.getEnvironment ()); } if (экземпляр Bean embeddedValuerESolverAware) {((EmbeddedValuerESolverAware) Bean) .setemBeddedValueresolver (new EmbeddedValuerESolver (this.ApplicationContext.getBeanFactory ())); } if (экземпляр Bean ancessionof resourceLoaderAware) {((ResourceLoaderAware) Bean) .SetResourceloAder (this.applicationContext); } if (экземпляр Bean of ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) Bean) .setApplicationEventPublisher (this.ApplicationContext); } if (экземпляр Bean ancessourceaware) {(((Messageourceaware) Bean) .SetMessAgesource (this.ApplicationContext); } if (exanceof antaintionof antaintextaware) {(((ApplicationContextAware) Bean) .SetApplicationContext (this.ApplicationContext); }}}Есть больше правил для использования. Например, следующий код может воспринимать ApplicationContext. После того, как весна создает этот боб, он ввеет в приложение Context, поэтому мы можем использовать этот контекст для завершения публикации событий.
открытый класс Hellobean реализует ApplicationContextaware {private ApplicationContext ApplicationContext; Приватная строка Helloword = "Привет! Мир!"; public void setApplicationContext (контекст ApplicationContext) {this.ApplicationContext = context; } public void Sethelloord (String Helloword) {this.helloord = helloword; } public String gethellOord () {ApplicationContext.publishEvent (new PropertyGetTedEvent ("[" + Helloword + "] заслуживает")); вернуть Helloword; }} 3. BeanFactoryPostProcessor, этот постпроцессор обычно используется для обработки расширенного интерфейса, созданного BeanFactory. Пример заключается в следующем. После инъекции этого боба он автоматически печатает количество введенных бобов после создания Beanfactory:
Общедоступный класс Beancounter реализует BeanFactoryPostProcessor {@Override public void postprocessbeanfactory (configurablelistablebeanfactory beanfactory), бросает Beansexception {System.out.println (beanfactory.getbeandefinitionCount ()); }} 4. Фабрика. Factorybean - это специальный боб, который позволяет впрынить в пружинные контейнеры и генерировать настоящие бобы, поэтому он может быть определен таким образом. Сама фабрика - это боб, который способен предоставлять бобы. Следующее начинается с вызова завода и рассказывает о том, как Spring использует этот боб.
Чтобы различить обычные бобы и фабричные бобы, весна также должна иметь процесс оценки их и обработки их специально. Этот процесс находится в getObjectforbeanInstance abstractbeanfactory
Защищенный объект getObjectForbeanInstance (Object BeaninStance, String name, String Beanname, RootBeandefinition MBD) {// Не позволяйте вызову кода попытаться обогнать фабрику, если боб не является фабрикой. if (beanfactoryutils.sfactoryDereference (name) &&! (BeaninStance ExanceOf FactoryBean)) {Throw New BeanisNotaFactoryException (TransformedBeanName (name), beaninStance.getClass ()); } // Теперь у нас есть экземпляр бобов, который может быть обычным бобом или фабрикой. // Если это фабрика, мы используем его для создания экземпляра бобов, если только вызывающий // действительно не хочет ссылку на завод. if (! (Экземпляр BeaninStance Factorybean) || beanfactoryutils.isfactoryDereference (name)) {return beaninStance; } Объект объекта = null; if (mbd == null) {object = getCachedObjectForceFactoryBean (beanName); } if (object == null) {// возвращать экземпляр боба с завода. Factorybean <?> Factory = (Factorybean <?>) BeaninStance; // Кэширует объект, полученный из Factorybean, если это синглтон. if (mbd == null && содержит beandefinition (beanname)) {mbd = getmergedlocalbeandefinition (beanname); } boolean synthetic = (mbd! = null && mbd.issynthetic ()); Object = getObjectFromFactoryBean (Factory, Beanname ,! Synthetic); } return object; } Видно, что если это обычный боб, он будет возвращен напрямую, и если это фабрика, последний вызов позвонит Factory.getObject для возврата конкретного объекта. Если вы думаете о всей весне как о абстрактной фабрике и при создании абстрактных бобов, Factorybean - это конкретная фабрика, которая производит необходимые вам объекты.
Весной много применений фабрики. Чтобы привести относительно распространенный пример, при интеграции SessionFactory в Hibernate обычно вводится SessionFactory, но этот SessionFactory на самом деле не является обычным бобом. Его можно создать просто путем введения его в файл конфигурации. Он имеет много индивидуальных деталей, поэтому Spring делает этот боб фабрикой и управляет своим производственным объектом.