4. Сегодня в программе
• Составляющие и жизненный цикл Спринга
• Виды Контекстов Спринга
• А как это сделать?..
• А как Спринг влияет на производительность?
9. BeanPostProcessor
• Позволяет настраивать наши бины до того, как они попадают в
контейнер
• У этого интерфейса 2 метода:
• Object postProcessBeforeInitialization(Object bean, String beanName)
• Object postProcessAfterInitialization(Object bean, String beanName)
• А между ними вызывается init метод
• init-method
• afterPropertiesSet
• @PostConstruct
10. У меня вопрос
А на хрена нужны инит методы?
Конструктора мало что ли?
11. А ты про двухфазовый
конструктор ничего не
слышал???
16. Еще один компонент ApplicationListener
• ContextStartedEvent
• ContextStoppedEvent
• ContextRefreshedEvent
• ContextClosedEvent
• Из любого ивента можно вытащить контекст
18. BeanFactoryPostProcessor
• Позволяет настравить бин дифиншны, до того, как создаются бины
• Этот интерфэйс имеет один единственный метод:
• postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
• Этот метод запустится на этапе, когда другие бины ещё не созданы,
и есть только BeanDefinitions и сам BeanFactory
21. ClassPathBeanDefinitionScanner
• Не является ни BeanPostProcessor-ом, ни BeanFactoryPostProcessor-ом
• Он ResourceLoaderAware
• Создаёт BeanDefinitions из всех классов,
над которыми стоит @Component,
или другая аннотация, аннотированная @Component
22. Java Config
• new AnnotationConfigApplicationContext(JavaConfig.class);
• Казалось бы, его должен парсировать, какой-нибудь BeanDefinitionReader,
как это было с XML
• И даже его класс его называется схоже: AnnotatedBeanDefinitionReader.
• Но нет, AnnotatedBeanDefinitionReader вообще ничего не имплементирует
• Он просто является часть ApplicationContext-a
• Он только регестрирует все JavaConfig-и
23. @Configuration
@ComponentScan("root")
public class JavaConfig {
@Bean
public CoolDao dao() {
return new CoolDaoImpl();
}
@Bean(initMethod = "init")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public CoolService coolService() {
CoolServiceImpl service = new CoolServiceImpl();
service.setDao(dao());
return service;
}
}
24. Кто обрабатывает JavaConfig?
• ConfigurationClassPostProcessor (особый BeanFactoryPostProcessor)
• Его регистрирует AnnotationConfigApplicationContext
• Он создаёт бин-дифинишны по @Bean
• А так же относится к:
• @Import
• @ImportResource
• @ComponentScan (да-да, там опять будет задействован крот)
25. Groovy Config
• Создаётся вот так:
new GenericGroovyApplicationContext("context.groovy");
• Парсируется GroovyBeanDefinitionReader
beans {
myDao(DaoImpl)
jeeConfService(JeeConfServiceImpl) { bean ->
bean.scope = 'prototype'
dao = myDao
}
}
28. Что будем мерить?
• Время создания объекта (new / reflection / Spring)
• Время на лукап и инжекшн
• Время создания прокси
• Время вызова метода через прокси
• Аспекты
41. Можно выдохнуть
• Сколько времени нужно на создание миллиона прототайпов?
• 4.5 секунды
• Сколько времени нужно чтобы получить миллион сингалтонов?
• 0.1 секунды
42.
43.
44. Выводы
• Хочешь, хорошо работать – пользуйся Спрингом
• Хочешь, чтобы работало хорошо – знай его кишки
Notes de l'éditeur
А как Спринг влияет на производительность?
Цена создания объекта
Prototype – против синглтона
Цена создания прокси
Цена вызова метода через прокси
Аспекты: как разные поинткаты бьют по производительности
А как это сделать?..
Обновление прототайпов в синглтоне при помощи JavaConfig
Протухание бинов
Custom Scopes
ApplicationContext регстрирует специальный BFPP ConfigurationClassPostProcessor который в том числе добавляет BeanDifinitions по @Bean, а также относится к @Import, @ImportResource, @ComponentScan (там в итоге пользуются тем же кротом)
AnnotatedBeanDefinitionReader Добавляет @Configuration, вначале делая проверку @Condition
Этот класс держит в себе ApplicationContext и он создаёт его в пустом конструкторе.
Дальше при помощи AnnotationConfigUtilsAnnotatedBeanDefinitionReader Подгружает все внутренние бин пост процессоры сприрнга (при помощи которых он будет настраивать нашу @Configuration И в конечном итоге AnnotatedBeanDefinitionReader Регистрирует все @Configuration, которые передали в конструктор ApplicationContexta
BeanDefinitionRegistryPostProcessor
Есть только одна имплементация: ConfigurationClassPostProcessorПри помощи ConfigurationClassParserПарсирует все @Configuration и ищет в них определение бинов ConfClassParser держит в себе ComponentScanAnnotationParser, который имеет ClassPathBeanDefinitionScannerКоторый он сначала пол часа настраивает (говорит ему какие пакеты сканировать, какие фильтры), а потом при его помощи сканирует и ищет все @Component
person.(class)=anlyze.Person person.name=Jeka person.(singleton)=false
public class PropertyFileApplicationContext extends GenericApplicationContext {
public PropertyFileApplicationContext(String fileName) {
BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(this);
reader.loadBeanDefinitions(new ClassPathResource(fileName));
refresh(); } }
Пофиг @Autowire над полем или сеттором
@Resource работает медленнее на 13%