JavaRush /Java Blog /Random-TL /Spring Framework. Panimula
Marchello
Antas
Санкт-Петербург

Spring Framework. Panimula

Nai-publish sa grupo
Kamusta! Habang ang pangangasiwa ng JavaRush ay nagtatrabaho sa mga bagong antas, gusto kong magsimula ng isang serye ng mga artikulo sa pagsasanay sa Spring Framework. Oo, alam ko na marami nang materyal sa paksang ito sa Internet, ngunit, bilang mga palabas sa pagsasanay, lahat sila ay nasa antas ng Hello World. Gusto kong pag-usapan hindi ang tungkol sa kung paano tama ang paglalagay ng mga anotasyon, ngunit tungkol sa kung paano gumagana ang lahat ng ito "sa ilalim ng hood." Ang artikulo ay inilaan para sa mga nakagawa na sa balangkas na ito sa isang paraan o iba pa at pamilyar sa mga pangunahing konsepto. Spring Framework. Введение - 1

Sinisimulan ang konteksto.

Kaya magsimula tayo sa mga pangunahing kaalaman. Sa palagay ko, isa sa mga pinakamahalagang punto ay upang maunawaan kung paano naka-set up ang konteksto at sinisimulan ang mga bean. Tulad ng alam mo, bago magsimulang gumana ang Spring , kailangan itong i-configure. Sa antediluvian times, ito ay ginawa gamit ang mga xml file (sa ilang mga proyekto, pangunahin sa mga luma, patuloy nilang ginagawa ito hanggang ngayon). Narito ang isang maliit na halimbawa ng naturang configuration file:
<?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-3.0.xsd">

   <bean id="helloWorld" class="ru.javarush.HelloWorld">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>
Sa pangkalahatan, ito ay sapat na upang lumikha ng isang pares ng mga controllers at maglunsad ng isang startup (na hindi mag-alis). Ngunit paano gagawin ng pagsasaayos na ito ang Spring? At narito kung saan nagiging kawili-wili ang mga bagay. Upang ang aming pagsasaayos ay maunawaan ng Spring, mayroong isang XmlBeanDefinitionReader. BeanDefinitionIto ay isang panloob na bahagi ng Spring na nag-scan (nag-parse) ng xml at lumilikha ng 's batay sa kung ano ang isinulat namin doon . BeanDefinitionay isang bagay na nag-iimbak ng impormasyon tungkol sa bean. Kabilang dito ang: mula sa aling klase ito (ang bean) dapat likhain; saklaw; kung naka-install ang tamad na pagsisimula; Kailangan bang magsimula bago ang bean na ito ng isa pa at iba pang mga katangian na inilarawan sa xml. Ang lahat ng natanggap BeanDefinitionay idinaragdag sa HashMap, kung saan ang identifier ay ang pangalan ng bean (itinakda mo o itinalaga ng Spring) at BeanDefinitionang mismong bagay. Matapos BeanDefinitionmalikha ang lahat, isang bagong bayani ang lilitaw sa entablado - BeanFactory. Ang bagay na ito ay umuulit sa HashMap’es BeanDefinition, lumilikha ng mga beans batay sa mga ito at inilalagay ang mga ito sa isang lalagyan ng IoC. Mayroong isang nuance dito, sa katunayan, kapag nagsimula ang application, ang lalagyan ng IoC ay maglalaman ng mga beans na mayroong saklaw ng Singleton (itinakda bilang default), habang ang iba ay nilikha kapag kinakailangan ang mga ito (prototype, kahilingan, session). At ngayon isang maliit na digression, kilalanin natin ang isa pang karakter.

Kilalanin ang BeanPostProcessor. (BPP)

bean post processorAng katotohanan ay ang isang bean ay hindi kinakailangang isang klase ng lohika ng negosyo para sa iyong aplikasyon. Ang isang bean ay tinatawag ding isang infrastructure bean. Sa madaling salita, ang isang infrastructure bean ay isang klase na nagko-configure ng iyong business logic beans (oo, masyadong maraming beans). Sasabihin ko sa iyo ang higit pa tungkol dito sa ibaba, ngunit upang gawing mas malinaw kung ano ang eksaktong kino-configure ng BPP, magbibigay ako ng isang halimbawa. Pamilyar ba ang lahat sa buod @Autowired? Kaya, AutowiredAnnotationBeanPostProcessorresponsable ka sa pagtiyak na ang lahat ng iyong mga klase ay naka-embed sa isa't isa. uknowimean

Bumalik tayo sa BeanFactory

Зная теперь о BPP, нужно уточнить, что итерируясь по HashMap’e с BeanDefinition’ами сперва создаются и кладутся отдельно (не в IoC контейнер) все BeanPostProcessor’ы. После этого создаются обычные бины нашей бизнес-логики, складываются в IoC-контейнер и начинается их настройка с помощью отдельно отложенных BPP. А происходит это вот How, каждый BPP имеет 2 метода:
postProcessorBeforeInitialization(Object bean, String beanName);
postProcessorAfterInitialization(Object bean, String beanName);
Происходит итерация по нашим бинам дважды. В первый раз вызывается метод postProcessorBeforeInitialization, а во второй раз вызывается метод postProcessorAfterInitialization. Наверняка возник вопрос, зачем нужны два метода, объясняю. Дело в том, что для обработки некоторых аннотаций (таких How @Transactional, например) наш бин заменяется proxy классом. Whatбы понять зачем это делается, нужно знать How работает @Transactional, а работает это вот How. В метод, помеченный данной аннотацией необходимо налету добавить еще пару строк codeа. Как это сделать? Верно, с помощью создания класса proxy, внутри которого и будет добавлен необходимый code в нужный метод. А теперь представим такую ситуацию, у нас есть класс:
class A {
    @Autowired
    private SomeClass someClass;

    @Transactional
    public void method() {
        // модификатор доступа обязательно public
    }
}
В этом классе 2 аннотации @Autowired и @Transactional. Обе аннотации обрабатываются разными BPP. Если первым отработает AutowiredBPP, то все будет в порядке, но если нет, то мы столкнемся с вот Howой проблемой. Дело в том, что когда создается класс proxy, то вся мета-информация теряется. Другими словами, информации об аннотации @Autowired в proxy классе не будет, а значит и AutowiredBPP не отработает, а значит наше поле someClass будет иметь meaning null, что, скорее всего, приведет к NPE. Также стоит знать, что между вызовами методов postProcessorBeforeInitialization и postProcessorAfterInitialization происходит вызов init-метода, если он есть. Это по-большому счету второй конструктор, но отличие в том, что в этот момент все наши зависимости уже внедрены в класс и мы можем к ним обратиться из init-метода. Итак, еще раз алгоритм инициализации контекста:
  1. XmlBeanDefinitionReader сканирует наш xml-конфигурационный файл.
  2. Создает BeanDefinition’ы и кладет их в HashMap.
  3. Приходит BeanFactory и из этой HashMap отдельно складывает все BeanPostProcessor’ы.
  4. Создает из BeanDefinition’ов бины и кладет их в IoC-контейнер.
  5. Тут приходят BPP и настраивают эти бины с помощью 2х методов.
  6. Готово.
Собственно, на этом всё, пишите понравилась вам статья и стоит ли продолжать писать подобные туториалы.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION