SlideShare a Scribd company logo
1 of 53
Download to read offline
The Spring Puzzlers:
Начало.
Ты кто такой?
linkd.in/jbaruch
stackoverflow.com/users/402053/jbaruch
Ты кто такой?
linkedin.com/in/evborisov
Вместе мы:
Свистнули идейку:
Свистнули идейку:
Свистнули идейку:
Свистнули идейку:
Похоже, но не совсем
1. Все еще Два клевых пацана
на сцене
2. Меньше хи-хи, больше
хардкора!
3. Вы все равно голосуете!
4. Спасибо dataart, luxoft,
eleks, и infusion за призы!
Аннотации Спринга в наследовании
implements
extends
extends
Аннотации Cпринга в наследовании
public class Parent {
@PostConstruct
private void init(){
System.out.println("Папа");
}
}
@Component
public class Son extends Parent {
@PostConstruct
public void init(){
System.out.println("Cын");
}
}
Создаём сына, что с папой?
A. @PostConstruct не inherited,
Поэтому Папа не придёт
B. init у Папы private,
поэтому Папа не придёт
C. Не может быть больше, чем один
init method – Папа не придёт
D. init method переопределён у
сына, поэтому папа не придёт
E. Папа придёт
Папа точно придёт
Аннотации спринга в наследовании
public class Parent {
@PostConstruct
private void init(){
System.out.println("Папа");
}
}
@Component
public class Son extends Parent {
@PostConstruct
public void init(){
System.out.println("Cын");
}
}
Создаём сына, что с папой?
A. @PostConstruct не inherited,
Поэтому Папа не придёт
B. init у Папы private,
поэтому Папа не придёт
C. Не может быть больше, чем один
init method – Папа не придёт
D. init method переопределён у
сына, поэтому папа не придёт
E. Папа придёт
@Service
public class JEEConfServiceImpl implements JEEConfService {
@Autowired
private String conference;
@Audit
public void pay() {
…
}
@PostConstruct
public void setup(){
…
}
}
Добавляем наш @Audit
A. Не сработает setup method
B. NoSuchBeanDefinitionException
C. Упадёт Autowired из за то, что у
прокси нет нужного филда
D. Всё будет хорошоcontext.getBean(JEEConfService.class).pay();
@Service
public class JEEConfServiceImpl implements
JEEConfService {
@Autowired
private String conference;
@Audit
public void pay() {
…
}
@PostConstruct
public void setup(){
System.out.println(conference);
}
}
Добавляем наш @Audit
A. Не сработает setup method
B. NoSuchBeanDefinitionException
C. Упадёт Autowired из за то, что у
прокси нет нужного филда
D. Всё будет хорошоcontext.getBean(JEEConfService.class).pay();
Как мы это чиним?
• Прокси надо делать после инит методов!
• Для это есть postProcessAfterInit
@Component
@Aspect
public class PayInformatorAspect {
@Pointcut("execution(* jeeconf..*.pay*(..))")
public void allPayMethods(){}
@After("allPayMethods()")
public void sendMailToAlimenkov(){
System.out.println("Ещё билет продали");
}
}
Добавим Аспект
A. Алименков получит извещение о проданном билете, но не аудита
B. Аудит будет, но Алименков не узнает о проданном билете
C. Будет аудит и Алименков получит извещение
D. Будет exception из-за двухуровневого прокси
Как мы это чиним?
• Пишем нормальный BPP, который не делает
bean.getClass()
Подключаем транзакции Cпринга
@Retention(RetentionPolicy.RUNTIME)
@Transactional
public @interface JEEConfTransaction {
Propagation propagation() default Propagation.REQUIRES_NEW;
}
@JEEConfTransaction
public class JEEConfService {
public void transferMoney(Account from, Account to, BigDecimal amount) {
withdraw(from, amount);
deposit(to, amount);
}
@Transactional(propagation = Propagation.MANDATORY)
private void withdraw(Account from, BigDecimal amount) {
//some code here
}
@Transactional(propagation = Propagation.REQUIRED)
private void deposit(Account to, BigDecimal amount) {
//some code here
informBankManager(amount);
}
private void informBankManager(BigDecimal amount) {
//some code here
}
}
Вложенные транзакции
C. Откатится до начала
метода deposit
D. Метод withdraw
кинет exception
A. Всё откатится
до самого начала
B. Откатится только
informBankManager
Случился exception
в методе
informBankManager.
Что будет?
Почему не работает??
@Service
public class JEEConfServiceImpl implements JEEConfService {
@Transactional
public void transferMoney(Account from, Account to, BigDecimal amount)
…
informAboutPayment();
}
@Override
@Transactional(requiresNew = true)
public void informAboutPayment() {
System.out.println("money were transferred");
}
}
Почему не работает??
@Service
public class JEEConfServiceImpl implements JEEConfService {
@Transactional
public void transferMoney(Account from, Account to, BigDecimal amount)
…
this.informAboutPayment();
}
@Override
@Transactional(requiresNew = true)
public void informAboutPayment() {
System.out.println("money were transferred");
}
}
Самовпрыскивание
Самовпрыскивание. Как сделать?
A. @Autowired
B. @Inject
C. @Resource
D. Что за бред?! Это невозможно!
У Cпринга 4 года, а у нас?
A. 4 часа
B. 4 дня
C. 4 минуты
D. 4 секунды
Разогреваем Cache
@Service
public class JEEConfServiceImpl implements JEEConfService
{
@Transactional
@PostConstruct
public void warmCache() {
…
}
@Override
public void processPayment() {
…
}
}
@Transactional @PostConstruct
• Что будет, с методом у которого обе аннотации?
A. Сработает с транзакцией
B. Сработает без транзакции
C. Не сработает вообще
D. MethodMissingException
ApplicationListener
• Решаем своей аннотацией @PostInitialize
Чего не будет в BeanDefinition-e?
@Bean
@Scope("singleton")
public String str() {
return "Chuck Norris";
} A. Scope
B. Bean name
C. BeanClass
D. Всё будет
@PostInitialize
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
BeanDefinition beanDefinition =
factory.getBeanDefinition(name);
String beanClassName = beanDefinition.getBeanClassName();
try {
Class<?> originalBeanClass = Class.forName(beanClassName);
Но ведь не так же…
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
BeanDefinition beanDefinition = factory.getBeanDefinition(name);
String beanClassName = beanDefinition.getBeanClassName();
try {
if (beanClassName == null) {
continue;
}
Class<?> originalBeanClass = Class.forName(beanClassName);
Сделаем по-взрослому
A. 4 минуты
B. 3 минуты
C. 2 минуты
D. 1 минуты
СТРАШНЫЕ ИСТОРИИ
МАЛЬЧИК, КОТОРЫЙ НЕ ЛЮБИЛ
ИНТЕРФЕЙСЫ
Добавляем Comparable…
A. NoSuchBeanDefinitionException
B. No proxies
C. NoSuchMethodException
D. All OK
Как мы это чиним?
• Любовь к интерфейсам
ДЕВОЧКА, КОТОРАЯ ХОТЕЛА СДЕЛАТЬ
НАДЕЖНО
Что будет?
@Service
public class MissionCriticalService {
@PostConstruct
public void important(){
System.out.println("Не забудь выключить утюг!");
}
}
<bean class=“jeeconf.littlegirl.MissionCriticalService"/>
<context:component-scan base-package="jeeconf.littlegirl"/>
@Bean
public MissionCriticalService missionCriticalService() {
return new MissionCriticalService();
}
A. не забыть выключить
утюг
B. не забыть выключить
утюг *2
C. не забыть выключить
утюг *3
D. BeanCreationException
Смотрим!
@Service
public class MissionCriticalService {
@PostConstruct
public void important(){
System.out.println("Не забудь выключить утюг!");
}
}
<bean class=“jeeconf.littlegirl.MissionCriticalService"/>
<context:component-scan base-package="jeeconf.littlegirl"/>
@Bean
public MissionCriticalService missionCriticalService() {
return new MissionCriticalService();
}
Выводы
1. Учите спринг!
2. Читайте документацию
3. Иногда это баги, И Иногда их
можно починить
4. Пользуйте spring integration в
intellij IDEA!
5. Учите спринг, Я сказал!
Spring puzzlers

More Related Content

What's hot

Easy selenium test automation on python
Easy selenium test automation on pythonEasy selenium test automation on python
Easy selenium test automation on pythonMykhailo Poliarush
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRAMBLER&Co
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаAlexander Kucherenko
 
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)SQALab
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and catscorehard_by
 
XPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriverXPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriverИлья Кожухов
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Применение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектовПрименение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектовPyNSK
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаAnton Arhipov
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Fedor Malyshkin
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Беглый обзор "внутренностей" Python
Беглый обзор "внутренностей" PythonБеглый обзор "внутренностей" Python
Беглый обзор "внутренностей" PythonMaxim Kulsha
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть IIPython Meetup
 
Ubuntu+python+selenium=легкий старт
Ubuntu+python+selenium=легкий стартUbuntu+python+selenium=легкий старт
Ubuntu+python+selenium=легкий стартAndrey Matukhno
 
Selenium: начало работы
Selenium: начало работыSelenium: начало работы
Selenium: начало работыPaul Stashevsky
 
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"QA Dnepropetrovsk Community (Ukraine)
 

What's hot (20)

Practical usage of RxJava 2
Practical usage of RxJava 2Practical usage of RxJava 2
Practical usage of RxJava 2
 
Easy selenium test automation on python
Easy selenium test automation on pythonEasy selenium test automation on python
Easy selenium test automation on python
 
Curse of spring boot test [VRN]
Curse of spring boot test [VRN]Curse of spring boot test [VRN]
Curse of spring boot test [VRN]
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на Swift
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языка
 
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
 
XPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriverXPath локаторы в Selenium WebDriver
XPath локаторы в Selenium WebDriver
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Применение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектовПрименение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектов
 
Selenium vs AJAX
Selenium vs AJAXSelenium vs AJAX
Selenium vs AJAX
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчика
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Беглый обзор "внутренностей" Python
Беглый обзор "внутренностей" PythonБеглый обзор "внутренностей" Python
Беглый обзор "внутренностей" Python
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть II
 
Ubuntu+python+selenium=легкий старт
Ubuntu+python+selenium=легкий стартUbuntu+python+selenium=легкий старт
Ubuntu+python+selenium=легкий старт
 
Bytecode
BytecodeBytecode
Bytecode
 
Selenium: начало работы
Selenium: начало работыSelenium: начало работы
Selenium: начало работы
 
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
Артем Розуменко - "Как и зачем разрабатывать собственный фреймворк?"
 

Similar to Spring puzzlers

Spring the Ripper by Evgeny Borisov
Spring the Ripper by Evgeny BorisovSpring the Ripper by Evgeny Borisov
Spring the Ripper by Evgeny BorisovJavaDayUA
 
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the ParenthesesThe Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the ParenthesesJavaDayUA
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Архитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьАрхитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьAndrey Bibichev
 
Страх и ненависть в Event Bus
Страх и ненависть в Event BusСтрах и ненависть в Event Bus
Страх и ненависть в Event Bus0leGG
 
Олег Годовых «Страх и ненависть в Event Bus»
Олег Годовых «Страх и ненависть в Event Bus»Олег Годовых «Страх и ненависть в Event Bus»
Олег Годовых «Страх и ненависть в Event Bus»DevDay
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterAleksandr Tarasov
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?Tatyanazaxarova
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptSergey Platonov
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#Andrey Karpov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Pythonru_Parallels
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на PythonCodeFest
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++Andrey Karpov
 
Android: Как написать приложение, которое не тормозит
Android: Как  написать приложение, которое не тормозитAndroid: Как  написать приложение, которое не тормозит
Android: Как написать приложение, которое не тормозитElena Kotina
 

Similar to Spring puzzlers (20)

Spring the Ripper by Evgeny Borisov
Spring the Ripper by Evgeny BorisovSpring the Ripper by Evgeny Borisov
Spring the Ripper by Evgeny Borisov
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the ParenthesesThe Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
 
Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
Архитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьАрхитектура в Agile: слабая связность
Архитектура в Agile: слабая связность
 
Страх и ненависть в Event Bus
Страх и ненависть в Event BusСтрах и ненависть в Event Bus
Страх и ненависть в Event Bus
 
Олег Годовых «Страх и ненависть в Event Bus»
Олег Годовых «Страх и ненависть в Event Bus»Олег Годовых «Страх и ненависть в Event Bus»
Олег Годовых «Страх и ненависть в Event Bus»
 
Jbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot StarterJbreak 2016: Твой личный Spring Boot Starter
Jbreak 2016: Твой личный Spring Boot Starter
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
JavaScript Intro
JavaScript IntroJavaScript Intro
JavaScript Intro
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Curse of spring boot test
Curse of spring boot testCurse of spring boot test
Curse of spring boot test
 
C#5 What's new?
C#5 What's new?C#5 What's new?
C#5 What's new?
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
 
Android: Как написать приложение, которое не тормозит
Android: Как  написать приложение, которое не тормозитAndroid: Как  написать приложение, которое не тормозит
Android: Как написать приложение, которое не тормозит
 
Spring Boot Test horror
Spring Boot Test horrorSpring Boot Test horror
Spring Boot Test horror
 

More from Evgeny Borisov

мифы о спарке
мифы о спарке мифы о спарке
мифы о спарке Evgeny Borisov
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Evgeny Borisov
 
Javaone 2013 moscow gradle english
Javaone 2013 moscow gradle   englishJavaone 2013 moscow gradle   english
Javaone 2013 moscow gradle englishEvgeny Borisov
 
Javaone 2013 moscow gradle
Javaone 2013 moscow gradleJavaone 2013 moscow gradle
Javaone 2013 moscow gradleEvgeny Borisov
 

More from Evgeny Borisov (6)

Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
мифы о спарке
мифы о спарке мифы о спарке
мифы о спарке
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
 
Spock
SpockSpock
Spock
 
Javaone 2013 moscow gradle english
Javaone 2013 moscow gradle   englishJavaone 2013 moscow gradle   english
Javaone 2013 moscow gradle english
 
Javaone 2013 moscow gradle
Javaone 2013 moscow gradleJavaone 2013 moscow gradle
Javaone 2013 moscow gradle
 

Spring puzzlers

  • 9. Похоже, но не совсем 1. Все еще Два клевых пацана на сцене 2. Меньше хи-хи, больше хардкора! 3. Вы все равно голосуете! 4. Спасибо dataart, luxoft, eleks, и infusion за призы!
  • 10.
  • 11.
  • 12. Аннотации Спринга в наследовании implements extends extends
  • 13. Аннотации Cпринга в наследовании public class Parent { @PostConstruct private void init(){ System.out.println("Папа"); } } @Component public class Son extends Parent { @PostConstruct public void init(){ System.out.println("Cын"); } } Создаём сына, что с папой? A. @PostConstruct не inherited, Поэтому Папа не придёт B. init у Папы private, поэтому Папа не придёт C. Не может быть больше, чем один init method – Папа не придёт D. init method переопределён у сына, поэтому папа не придёт E. Папа придёт
  • 15. Аннотации спринга в наследовании public class Parent { @PostConstruct private void init(){ System.out.println("Папа"); } } @Component public class Son extends Parent { @PostConstruct public void init(){ System.out.println("Cын"); } } Создаём сына, что с папой? A. @PostConstruct не inherited, Поэтому Папа не придёт B. init у Папы private, поэтому Папа не придёт C. Не может быть больше, чем один init method – Папа не придёт D. init method переопределён у сына, поэтому папа не придёт E. Папа придёт
  • 16.
  • 17. @Service public class JEEConfServiceImpl implements JEEConfService { @Autowired private String conference; @Audit public void pay() { … } @PostConstruct public void setup(){ … } } Добавляем наш @Audit A. Не сработает setup method B. NoSuchBeanDefinitionException C. Упадёт Autowired из за то, что у прокси нет нужного филда D. Всё будет хорошоcontext.getBean(JEEConfService.class).pay();
  • 18.
  • 19. @Service public class JEEConfServiceImpl implements JEEConfService { @Autowired private String conference; @Audit public void pay() { … } @PostConstruct public void setup(){ System.out.println(conference); } } Добавляем наш @Audit A. Не сработает setup method B. NoSuchBeanDefinitionException C. Упадёт Autowired из за то, что у прокси нет нужного филда D. Всё будет хорошоcontext.getBean(JEEConfService.class).pay();
  • 20. Как мы это чиним? • Прокси надо делать после инит методов! • Для это есть postProcessAfterInit
  • 21. @Component @Aspect public class PayInformatorAspect { @Pointcut("execution(* jeeconf..*.pay*(..))") public void allPayMethods(){} @After("allPayMethods()") public void sendMailToAlimenkov(){ System.out.println("Ещё билет продали"); } } Добавим Аспект A. Алименков получит извещение о проданном билете, но не аудита B. Аудит будет, но Алименков не узнает о проданном билете C. Будет аудит и Алименков получит извещение D. Будет exception из-за двухуровневого прокси
  • 22.
  • 23. Как мы это чиним? • Пишем нормальный BPP, который не делает bean.getClass()
  • 24. Подключаем транзакции Cпринга @Retention(RetentionPolicy.RUNTIME) @Transactional public @interface JEEConfTransaction { Propagation propagation() default Propagation.REQUIRES_NEW; }
  • 25. @JEEConfTransaction public class JEEConfService { public void transferMoney(Account from, Account to, BigDecimal amount) { withdraw(from, amount); deposit(to, amount); } @Transactional(propagation = Propagation.MANDATORY) private void withdraw(Account from, BigDecimal amount) { //some code here } @Transactional(propagation = Propagation.REQUIRED) private void deposit(Account to, BigDecimal amount) { //some code here informBankManager(amount); } private void informBankManager(BigDecimal amount) { //some code here } } Вложенные транзакции C. Откатится до начала метода deposit D. Метод withdraw кинет exception A. Всё откатится до самого начала B. Откатится только informBankManager Случился exception в методе informBankManager. Что будет?
  • 26.
  • 27. Почему не работает?? @Service public class JEEConfServiceImpl implements JEEConfService { @Transactional public void transferMoney(Account from, Account to, BigDecimal amount) … informAboutPayment(); } @Override @Transactional(requiresNew = true) public void informAboutPayment() { System.out.println("money were transferred"); } }
  • 28. Почему не работает?? @Service public class JEEConfServiceImpl implements JEEConfService { @Transactional public void transferMoney(Account from, Account to, BigDecimal amount) … this.informAboutPayment(); } @Override @Transactional(requiresNew = true) public void informAboutPayment() { System.out.println("money were transferred"); } }
  • 30. Самовпрыскивание. Как сделать? A. @Autowired B. @Inject C. @Resource D. Что за бред?! Это невозможно!
  • 31.
  • 32. У Cпринга 4 года, а у нас? A. 4 часа B. 4 дня C. 4 минуты D. 4 секунды
  • 34. @Service public class JEEConfServiceImpl implements JEEConfService { @Transactional @PostConstruct public void warmCache() { … } @Override public void processPayment() { … } }
  • 35. @Transactional @PostConstruct • Что будет, с методом у которого обе аннотации? A. Сработает с транзакцией B. Сработает без транзакции C. Не сработает вообще D. MethodMissingException
  • 36.
  • 37. ApplicationListener • Решаем своей аннотацией @PostInitialize
  • 38. Чего не будет в BeanDefinition-e? @Bean @Scope("singleton") public String str() { return "Chuck Norris"; } A. Scope B. Bean name C. BeanClass D. Всё будет
  • 39.
  • 40. @PostInitialize String[] names = context.getBeanDefinitionNames(); for (String name : names) { BeanDefinition beanDefinition = factory.getBeanDefinition(name); String beanClassName = beanDefinition.getBeanClassName(); try { Class<?> originalBeanClass = Class.forName(beanClassName);
  • 41. Но ведь не так же… String[] names = context.getBeanDefinitionNames(); for (String name : names) { BeanDefinition beanDefinition = factory.getBeanDefinition(name); String beanClassName = beanDefinition.getBeanClassName(); try { if (beanClassName == null) { continue; } Class<?> originalBeanClass = Class.forName(beanClassName);
  • 42. Сделаем по-взрослому A. 4 минуты B. 3 минуты C. 2 минуты D. 1 минуты
  • 44. МАЛЬЧИК, КОТОРЫЙ НЕ ЛЮБИЛ ИНТЕРФЕЙСЫ
  • 45. Добавляем Comparable… A. NoSuchBeanDefinitionException B. No proxies C. NoSuchMethodException D. All OK
  • 46.
  • 47. Как мы это чиним? • Любовь к интерфейсам
  • 48. ДЕВОЧКА, КОТОРАЯ ХОТЕЛА СДЕЛАТЬ НАДЕЖНО
  • 49. Что будет? @Service public class MissionCriticalService { @PostConstruct public void important(){ System.out.println("Не забудь выключить утюг!"); } } <bean class=“jeeconf.littlegirl.MissionCriticalService"/> <context:component-scan base-package="jeeconf.littlegirl"/> @Bean public MissionCriticalService missionCriticalService() { return new MissionCriticalService(); } A. не забыть выключить утюг B. не забыть выключить утюг *2 C. не забыть выключить утюг *3 D. BeanCreationException
  • 50.
  • 51. Смотрим! @Service public class MissionCriticalService { @PostConstruct public void important(){ System.out.println("Не забудь выключить утюг!"); } } <bean class=“jeeconf.littlegirl.MissionCriticalService"/> <context:component-scan base-package="jeeconf.littlegirl"/> @Bean public MissionCriticalService missionCriticalService() { return new MissionCriticalService(); }
  • 52. Выводы 1. Учите спринг! 2. Читайте документацию 3. Иногда это баги, И Иногда их можно починить 4. Пользуйте spring integration в intellij IDEA! 5. Учите спринг, Я сказал!