|
|
Строка 1: |
Строка 1: |
| == Жизненный цикл Spring Bean ==
| | [[:Категория:Работа]] |
| [[Файл:SpringBeanLifeCycle.png|безрамки|800x800пкс]] | |
| === InitializingBean ===
| |
| Вызывается метод afterPropertiesSet(), который служит той же цели, что и метод init()
| |
| === @PostConstruct ===
| |
| Начиная с версии Spring 2.5, поддерживаются также и аннотации JSR-250 для указания метода,
| |
| который платформа Spring должна вызвать, если соответствующая аннотация,
| |
| связанная с жизненным циклом бина, существует в классе.
| |
| Это тот же init-method, только имя метода может быть любым.
| |
| Для работы необходимо добавить дескриптор context:annotation-config.
| |
|
| |
|
| === DisposableBean === | | = Начало = |
| Вызывается метод destroy(), который служит той же цели, что и метод указываемый в атрибуте destroy-metod.
| | https://www.tensorflow.org/ |
|
| |
|
| === @PreDestroy ===
| | Текущая версия v1.5.0 |
| Применение аннотации жизненного цикла @PreDestroy, определенной в стандарте JSR-250,
| |
| которая является противоположностью @PostConstruct.
| |
| Для работы необходимо добавить дескриптор context:annotation-config.
| |
|
| |
|
| = Конфигурация XML =
| | Docker: https://hub.docker.com/r/tensorflow/tensorflow/ |
| == beans ==
| |
| === beans default-lazy-init ===
| |
| Атрибут инструктирует Spring о том, что экземпляры бинов, определенных в конфигурационном файле,
| |
| должны создаваться только при их запросе приложением.
| |
| <nowiki> <beans ... default-lazy-init = "true">
| |
| <bean ... />
| |
| ...
| |
| </beans></nowiki>
| |
|
| |
|
| == context:component-scan ==
| | Using TensorFlow via Docker https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/docker/README.md |
| Дескриптор <context:component-scan> сообщает Spring о необходимости
| |
| сканирования кода на предмет внедряемых бинов, аннотированных с помощью
| |
| @Component, @Controller, @Repository и @Service, а также поддерживающих
| |
| аннотации @Autowired и @Inject в указанном пакете (и всех eгo внутренних па
| |
| кетах). В дескрипторе <context:component-scan> можно определить множество
| |
| пакетов, используя в качестве разделителя запятую, точку запятой или пробел.
| |
| Кроме того, для более детализированного управления этот дескриптор поддерживает
| |
| включение и исключение сканирования компонентов.
| |
| Также можно указать пакет для сканирования через установку атрибута base-package.
| |
| Еще можно указать исключения через context:exclude-filter.
| |
|
| |
|
| == bean == | | = Загрузка = |
| === bean/property ===
| | Для CPU:<syntaxhighlight> |
| name - Имя свойства бина
| | docker pull gcr.io/tensorflow/tensorflow |
| value - значение (простой тип)
| | </syntaxhighlight> |
|
| |
|
| До версии 2.5:
| | = Запуск = |
| ref - ссылка на другой бин по id
| | Для CPU:<syntaxhighlight> |
| Применение атрибута local означает, что дескриптор ref всегда просматривает только идентификатор бина и никогда не принимает во внимание его псевдонимы:
| | docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow |
| <nowiki><ref local="test"/></nowiki>
| | </syntaxhighlight> |
| Более того, определение бина должно существовать в том же самом ХМL-файле конфигурации.
| |
|
| |
|
| Пример ссылки на бин (ссылка текущий, дочерний, родительский контекст)
| | <syntaxhighlight> |
| <nowiki><ref bean="newBean"/></nowiki>
| | $ docker run -it -p 8888:8888 gcr.io/tensorflow/tensorflow |
| Пример ссылки на бин родительского контекста
| | [I 17:30:28.871 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret |
| <nowiki><ref parent="newBean"/></nowiki>
| | [W 17:30:28.898 NotebookApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended. |
| С версии 2.5: конфигурировать можно не через property, а в самом bean так:
| | [I 17:30:28.903 NotebookApp] Serving notebooks from local directory: /notebooks |
| p:<тут имя свойства>-ref="id другого бина"
| | [I 17:30:28.904 NotebookApp] 0 active kernels |
| или так
| | [I 17:30:28.904 NotebookApp] The Jupyter Notebook is running at: |
| p:<тут имя свойства>="простое значение"
| | [I 17:30:28.904 NotebookApp] http://[all ip addresses on your system]:8888/?token=9fc3be91c196e8fe264d384f0a07aaba99d589c1288067a5 |
| Через SpEL:
| | [I 17:30:28.904 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). |
| p:name = "#{injectSimpleConfig.name}"
| | [C 17:30:28.904 NotebookApp] |
| | |
| | Copy/paste this URL into your browser when you connect for the first time, |
| | to login with a token: |
| | http://localhost:8888/?token=9fc3be91c196e8fe264d384f0a07aaba99d589c1288067a5 |
| | </syntaxhighlight> |
|
| |
|
| ==== bean/property/map ====
| | При запуске будут доступны 3 обширных урока на английском о том, как работать с этой системой |
| Пример:
| |
| <nowiki><property name="map">
| |
| <map>
| |
| <entry key="v1">
| |
| <value>Hello World!</value>
| |
| </entry>
| |
| <entry key="refToBean">
| |
| <ref local="localBeanId"/>
| |
| </entry>
| |
| </map>
| |
| </property></nowiki>
| |
|
| |
|
| ==== bean/property/set ==== | | = Запуск TensorBoard = |
| | <syntaxhighlight> |
| | docker exec -ti 6523620b7eb2 /bin/sh |
| | # tensorboard --logdir=/tmp/tensorflow/mnist/logs/ |
| | </syntaxhighlight> |
| | где 6523620b7eb2 - id контейнера tensorflow |
|
| |
|
| <nowiki><property name="set">
| | Интерфейс tensorboard будет доступен по адресу http://127.0.0.1:6006/ |
| <set>
| |
| <value>Hello World 1 </value>
| |
| <ref local="oracle" />
| |
| </set>
| |
| </property></nowiki>
| |
|
| |
|
| ==== bean/property/list ====
| | [[Категория:Работа]] |
| | | [[Категория:AI]] |
| <nowiki><property name="list">
| |
| <list>
| |
| <value>Hello World!</value>
| |
| <ref local="localBeanId"/>
| |
| </list>
| |
| </property></nowiki>
| |
| | |
| ==== bean/property/props ====
| |
| Дескриптор <props> позволяет передавать в качестве значений только String,
| |
| потому что класс Properties разрешает только значения свойств типа String.
| |
| Пример:
| |
| <property name="props">
| |
| <props>
| |
| <prop key="firstName">Sasha</prop>
| |
| <prop key="secondName">V.</prop>
| |
| </props>
| |
| </property>
| |
| | |
| === bean/constructor-arg ===
| |
| До версии 3.1:
| |
| constructor-arg определяет Constructor Injection.
| |
| Всегда лучше применять атрибут index, чтобы избежать путаницы между параметрами.
| |
| | |
| С версии 3.1: можно применять в bean выражение вида c:<свойство>=<значение>
| |
| или _<digit> - как указание индекса аргумента конструктора
| |
| <bean id="message" class="java.lang.String" с:_O="message"/>
| |
| | |
| Если есть 2 конструктора с одинаковыми именами параметров, то можно указать тип
| |
| <constructor-arg type="int"><value>1</value><constructor-arg>
| |
| | |
| === bean/lookup-method ===
| |
| Пример Method Injection:
| |
| <nowiki> <bean id="abstractLookupBean" class="com.a.AЬstractLookupDemoBean">
| |
| <lookup-method name="getMyHelper" bean="helper"/>
| |
| </bean></nowiki>
| |
| | |
| === bean/replaced-method ===
| |
| <nowiki> <bean id="replacementTarget" class="com.a.ReplacementTarget">
| |
| <replaced-method name="formatMessage" replacer="methodReplacer">
| |
| <arg-type>String</arg-type>
| |
| </replaced-method>
| |
| </bean></nowiki>
| |
| === bean name-алиасы ===
| |
| Через name:
| |
| <nowiki><bean id="name1" name="name2 name3,name4;name5" class="java.lang.String"/></nowiki>
| |
| Через alias:
| |
| <nowiki><alias name = "namel" alias = "name6"/></nowiki>
| |
| | |
| Извлечь список псевдонимов бина можно с помощью вызова метода ApplicationContext.getAliases(String) с передачей ему любого из имен бина или его идентификатора. Этот метод возвращает в виде массива String список псевдонимов, содержащий все псевдонимы кроме указанного при вызове.
| |
| | |
| === bean scope ===
| |
| По умолчанию Spring устанавливает атрибут scope в singleton (одиночный).
| |
| Область действия на уровне prototype (прототип) заставляет Spring создавать новый экземпляр бина каждый раз, когда он запрашивается приложением.
| |
| Пример:
| |
| <nowiki><bean id="nonSingleton" class="java.lang.String" scope="prototype" c:_0="Sasha V."/></nowiki>
| |
| | |
| === bean depends-on ===
| |
| В следующей конфигурации мы утверждаем, что бин по имени beanA зависит от бина
| |
| под названием beanB.
| |
| <nowiki> <bean id="beanA" class="BeanA" depends-on="beanB"/>
| |
| <bean id="beanB" class="BeanB"/></nowiki>
| |
| Во время разработки приложений такого подхода лучше избегать; вместо этого определяйте зависимости с помощью контрактов Setter Injection и Constructor Injection.
| |
| | |
| === bean autowire ===
| |
| В атрибуте autowire для бина понадобится указать используемый режим автосвязывания.
| |
| Платформа Spring поддерживает следующие режимы автосвязывания: byName, ЬуТуре, constructor, default и no (автосвязывание отключено; устанавливается по умолчанию).
| |
| | |
| === bean lazy-init ===
| |
| Атрибут lazy-init устанавливается в true, чтобы информировать Spring о необходимости создания экземпляра бина только при первом его запросе, а не во время начальной загрузки.
| |
| | |
| === bean parent ===
| |
| Наследование бинов:
| |
| <nowiki> <bean id="inheritParent" class="SimpleBean" p:name="Name1" p:age="32"/>
| |
| <bean id="inheritChild" class="SimpleBean" parent="inheritParent" р:аgе="ЗЗ"/></nowiki>
| |
| | |
| === bean abstract ===
| |
| В случае если определение родительского бина не должно быть доступным для поиска из ApplicationContext,
| |
| к дескриптору bean, объявляющему родительский бин, можно добавить атрибут abstract="true".
| |
| | |
| === bean init-method ===
| |
| Атрибут init-method, который сообщает платформе Spring, что она должна вызвать метод init(),
| |
| как только завершит конфигурирование бина.
| |
| <nowiki><bean id="iBean" class="BeanClass" init-method="init"/></nowiki>
| |
| Аналоги: InitializingBean.afterPropertiesSet(), @PostConstruct
| |
| | |
| === bean destroy-method ===
| |
| Чтобы назначить метод для вызова во время уничтожения бина, нужно просто указать имя этого метода в атрибуте destroy-method дескриптора <bean> для бина.
| |
| Платформа Spring вызывает этот метод непосредственно перед уничтожением одиночного экземпляра бина (она не будет вызывать этот метод для бинов с областью действия на уровне прототипа).
| |
| <nowiki><bean id="dBean" class="BeanClass" destroy-method="destroy"/></nowiki>
| |
| Аналоги: DisposableBean.destroy(), @PreDestroy
| |
| | |
| == util ==
| |
| Пространство имен util, предоставляемое Spring, для объявления бинов, хранящих свойства коллекций.
| |
| === util:map ===
| |
| <nowiki> <util:map id="map" map-class = "java.util.HashMap">
| |
| <entry key = "someValue">
| |
| <value>Hello World!</value>
| |
| </entry>
| |
| <entry key="someBean">
| |
| <ref bean="beanId"/>
| |
| </entry>
| |
| </util:map></nowiki>
| |
| | |
| === util:properties ===
| |
| <nowiki> <util:properties id="props">
| |
| <prop key="firstName">Sasha</prop>
| |
| <prop key = "secondName">V.</prop>
| |
| </util:properties></nowiki>
| |
| | |
| === util:set ===
| |
| <nowiki> <util: set id="set">
| |
| <value>Hello World!</value>
| |
| <ref bean = "oracle"/>
| |
| </util: set></nowiki>
| |
| | |
| === util:list ===
| |
| <nowiki> <util:list id="list">
| |
| <value>Hello World!</value>
| |
| <ref bean="oracle"/>
| |
| </util:list></nowiki>
| |
| | |
| = Кофигурация аннотациями =
| |
| == @Autowired ==
| |
| Если указано на setter, то происходит автоматическое связывание.
| |
| | |
| Если указано на construcor, то происходит автоматическая передача параметра, пример:
| |
| @Autowired
| |
| public NewConstructor (@Value ( "message") String message) {
| |
| this.message = message;
| |
| }
| |
| Аннотация @Autowired может быть применена только к одному из методов конструкторов.
| |
| | |
| == @Inject ==
| |
| В спринг аналогична автоматическому связыванию (JSR-299).
| |
| | |
| == @Resource ==
| |
| Пример - @Resource (name = "messageProvider") указывается для поддержки автоматического связывания. (JSR-250)
| |
| | |
| == @Value ==
| |
| Предназначена для определения значения, подлежащего внедрению.
| |
| Свойства:
| |
| @Value("32")
| |
| private int age;
| |
| Через SpEL:
| |
| @Value("#{injectSimpleConfig.name}")
| |
| | |
| | |
| Жесткое кодирование значения не является удачной идеей, т.к. его изменение влечет за собой перекомпиляцию программы.
| |
| | |
| == @Service ==
| |
| Пример - @Service("messageRenderer") указывает, что этот бин предоставляет службы,
| |
| которые могут требоваться другим бинам; в качестве параметра аннотации передается имя бина.
| |
| | |
| == @Component ==
| |
| @Component("injectSimpleConfig")
| |
| @Service является специализацией @Component, отражающей тот факт, что аннотированный класс предоставляет бизнес-службу другим уровням внутри приложения.
| |
| = Классы Spring =
| |
| == StopWatch ==
| |
| org.springframework.util.StopWatch - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения.
| |
| StopWatch stopWatch = new StopWatch();
| |
| stopWatch.start("demo");
| |
| for (int х = О; х < 100000; х++) {
| |
| MyHelper helper = bean.getMyHelper();
| |
| helper.doSomethingHelpful();
| |
| }
| |
| stopWatch.stop();
| |
| System. out. println ( "100000 gets took " + stopWatch. getTotalTimeMillis () + " ms");
| |
| == AbstractApplicationContext ==
| |
| === AbstractApplicationContext.registerShutdownHook ===
| |
| registerShutdownHook - создать перехватчик завершения (shutdown hook) - поток, который выполняется непосредственно перед завершением приложения.
| |
| Это отличный способ вызвать метод destroy () вашего класса AbstractApplicationContext (который расширяется всеми конкретными реализациями ApplicationContext).
| |
| | |
| Пример для автономного приложения:
| |
| ctx.load("classpath:META-INF/spring/app-context-annotation.xml");
| |
| ctx.registerShutdownHook();
| |
| ctx.refresh ();
| |
| Можно определить бин, который автоматом сделает тоже самое
| |
| <nowiki><bean id="shutdownHook" class="ShutdownHookBean"/></nowiki>
| |
| где ShutdownHookBean implements ApplicationContextAware
| |
| с таким методом setApplicationContext:
| |
| if (ctx instanceof GenericApplicationContext) {
| |
| ((GenericApplicationContext)ctx).registerShutdownHook();
| |
| }
| |
| | |
| === AbstractApplicationContext.destroy ===
| |
| Единственный недостаток обратных вызовов уничтожения в Spring связан с тем, что они не запускаются автоматически, т.е. перед закрытием приложения нужно не забыть вызвать AbstractApplicationContext.destroy(). Когда приложение выполняется как сервлет, указанный метод destroy() можно вызвать в методе destroy() сервлета. Однако в автономном приложении все не так просто, особенно при наличии множества точек выхода из приложения.
| |
| К счастью, решение есть. Java позволяет создать перехватчик завершения (shutdown hook). См. AbstractApplicationContext.registerShutdownHook
| |
| | |
| == BeanNameAware ==
| |
| Интерфейс BeanNameAware, который бин может реализовать, чтобы получить свое имя, имеет единственный метод: setBeanName (String)
| |
| == ApplicationContextAware ==
| |
| Интерфейс ApplicationContextAware, который бин может реализовать, чтобы получить ссылку на контекст ApplicationContext, который их сконфигурировал.
| |
| Имеет метод:
| |
| setApplicationContext(ApplicationContext ctx) throws BeansException
| |