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

Spring puzzlers

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
    Похоже, но несовсем 1. Все еще Два клевых пацана на сцене 2. Меньше хи-хи, больше хардкора! 3. Вы все равно голосуете! 4. Спасибо dataart, luxoft, eleks, и infusion за призы!
  • 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. Папа придёт
  • 14.
  • 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. Папа придёт
  • 17.
    @Service public class JEEConfServiceImplimplements 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();
  • 19.
    @Service public class JEEConfServiceImplimplements 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 из-за двухуровневого прокси
  • 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. Что будет?
  • 27.
    Почему не работает?? @Service publicclass 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 publicclass 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"); } }
  • 29.
  • 30.
    Самовпрыскивание. Как сделать? A.@Autowired B. @Inject C. @Resource D. Что за бред?! Это невозможно!
  • 32.
    У Cпринга 4года, а у нас? A. 4 часа B. 4 дня C. 4 минуты D. 4 секунды
  • 33.
  • 34.
    @Service public class JEEConfServiceImplimplements JEEConfService { @Transactional @PostConstruct public void warmCache() { … } @Override public void processPayment() { … } }
  • 35.
    @Transactional @PostConstruct • Чтобудет, с методом у которого обе аннотации? A. Сработает с транзакцией B. Сработает без транзакции C. Не сработает вообще D. MethodMissingException
  • 37.
    ApplicationListener • Решаем своейаннотацией @PostInitialize
  • 38.
    Чего не будетв BeanDefinition-e? @Bean @Scope("singleton") public String str() { return "Chuck Norris"; } A. Scope B. Bean name C. BeanClass D. Всё будет
  • 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 минуты
  • 43.
  • 44.
    МАЛЬЧИК, КОТОРЫЙ НЕЛЮБИЛ ИНТЕРФЕЙСЫ
  • 45.
    Добавляем Comparable… A. NoSuchBeanDefinitionException B.No proxies C. NoSuchMethodException D. All OK
  • 47.
    Как мы эточиним? • Любовь к интерфейсам
  • 48.
    ДЕВОЧКА, КОТОРАЯ ХОТЕЛАСДЕЛАТЬ НАДЕЖНО
  • 49.
    Что будет? @Service public classMissionCriticalService { @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
  • 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. Учите спринг, Я сказал!