О себе
• Пишу на джаве с 2001
• Преподаю джаву с 2003
• Консультирую с 2008
• Арихтектор с 2009
• Пилю стартап с 2014
• Техлид по биг дате с 2015
• Naya technologies c 2015
Spring puzzlers2
Мальчик, который доверял интерфейсам
public interface Утюг {
@PostConstruct
void разогреваться();
}
@Component
public class СуперДуперУтюг implements Утюг {
@Override
public void разогреваться() {
System.out.println("разогреваюсь");
}
@PostConstruct
@Autowired
public void гретьВоду(Вода вода){
System.out.println(вода+" грейся...");
}
}
A. Вода грейся
B. Вода грейся & Разогреваюсь
@Component
public class Вода {
@Override
public String toString() {
return "вода";
}
}
C. Разогреваюсь
D. Что то пойдёт не так
Что будет?
IllegalStateException
• method annotation requires a no-arg method: public void
iLoveInterfaces.СуперДуперУтюг.гретьВоду
Как чиним?
• Убираем @Postconstruct с метода помеченного @Autowired
@PostConstruct
@Autowired
public void гретьВоду(Вода вода){
System.out.println(вода+" грейся...");
}
public interface Утюг {
@PostConstruct
void разогреваться();
}
@Component
public class СуперДуперУтюг implements Утюг {
@Override
public void разогреваться() {
System.out.println("разогреваюсь");
}
@Autowired
public void гретьВоду(Вода вода){
System.out.println(вода+" грейся...");
}
}
A. Вода грейся
B. Вода грейся & Разогреваюсь
@Component
public class Вода {
@Override
public String toString() {
return "вода";
}
}
C. Разогреваюсь
D. Вообще ничего не напечатается
Что будет?
Да ну на…
public interface Утюг {
@PostConstruct
void разогреваться();
}
@Component
public class СуперДуперУтюг implements Утюг {
@Override
public void разогреваться() {
System.out.println("разогреваюсь");
}
@Autowired
public void гретьВоду(Вода вода){
System.out.println(вода+" грейся...");
}
}
A. Вода грейся
B. Вода грейся & Разогреваюсь
@Component
public class Вода {
@Override
public String toString() {
return "вода";
}
}
C. Разогреваюсь
D. Вообще ничего не напечатается
Что будет?
АННОТАЦИИ НЕ РАБОТАЮТ
В ИНТЕРФЕЙСАХ
Придётся написать BeanPostProcessor
Достал уже со своими BeanPostProcessors
Будем сегодня писать BPP?
Будем сегодня писать BPP?
• Напишем BeanFactoryPostProcessor
Не будем повторять ошибки Спринга
• Это не правильно, что за Postconstruct отвечает BPP
BeanDefinition – это интерфейс
• AbstractBeanDefinition
• AnnotatedBeanDefinition
• ConfigurationClassBeanDefinition
• GenericBeanDefinition
• ScannedGenericBeanDefinition
BeanDefinition – это интерфейс
• AnnotatedBeanDefinition
• AbstractBeanDefinition
• ConfigurationClassBeanDefinition
• GenericBeanDefinition
• ScannedGenericBeanDefinition
• AbstractBeanDefinition
• AnnotatedBeanDefinition
• ConfigurationClassBeanDefinition
• GenericBeanDefinition
• ScannedGenericBeanDefinition
Та не…
• AnnotatedBeanDefinition
• AbstractBeanDefinition
• ConfigurationClassBeanDefinition
• GenericBeanDefinition
• ScannedGenericBeanDefinition
Хрен тебе
class ConfigurationClassBeanDefinitionReader {
}
private static class ConfigurationClassBeanDefinition
extends RootBeanDefinition implements AnnotatedBeanDefinition
Package
friendly
Когда не получается закастить по хорошему…
Пошли ковырять то, что спрятано
Сага о двух программистах
@Configuration
public class BaruchConfig {
@Bean
public String str1() {return "Groovy";}
@Bean
public String str2() {return "Spring";}
}
@Configuration
public class JekaConfig {
@Bean
public List<String> messages() {
ArrayList<String> strings = new ArrayList<>();
strings.add("Groovy");
strings.add("Spring");
return strings;
}
}
@Service
public class BaruchService {
@Autowired
private List<String> list;
@Service
public class JekaService {
@Autowired
private List<String> list;
Что заинжектится в лист?
1. Groovy, Spring, Groovy, Spring
2. Groovy, Spring
3. Groovy, Spring, [Groovy, Spring]
4. Exception
А в чём тут был
паззлер?
Как-то на корпоративе
Пока Жека дров не наломал я подстрахуюсь
@Configuration
public class BaruchConfig {
@Bean @BaruchQualifier
public String str1() {return "Groovy";}
@Bean @BaruchQualifier
public String str2() {return "Spring";}
}
@Service
public class BaruchService {
@Autowired @BaruchQualifier
private List<String> list;
@Configuration
public class JekaConfig {
@Bean
public List<String> messages() {
ArrayList<String> strings = new ArrayList<>();
strings.add("Groovy");
strings.add("Spring");
return strings;
}
}
@Service
public class JekaService {
@Autowired
private List<String> list;
1. У Баруха всё хорошо
2. У Жеки всё хорошо
3. У нас обоих всё хорошо
4. У нас обоих всё плохо
@Configuration
public class BaruchConfig {
@Bean @BaruchQualifier
public String str1() {return "Groovy";}
@Bean @BaruchQualifier
public String str2() {return "Spring";}
}
@Service
public class BaruchService {
@Autowired @BaruchQualifier
private List<String> list;
Что теперь будет?
Ну когда уже будет
паззлер?
А теперь можно добавить Артифактори
@Configuration
public class JekaConfig {
@Bean
public List<String> messages() {
ArrayList<String> strings = new ArrayList<>();
strings.add("Groovy");
strings.add("Spring");
return strings;
}
}
@Service
public class JekaService {
@Autowired
private List<String> list;
Да Нет
@Configuration
public class BaruchConfig {
@Bean @BaruchQualifier
public String str1() {return "Groovy";}
@Bean @BaruchQualifier
public String str2() {return "Spring";}
@Bean @BaruchQualifier
public String str3() {return "Artifactory";}
}
@Service
public class BaruchService {
@Autowired @BaruchQualifier
private List<String> list;
Повлияет ли это на лист Жеки?
Какого хрена тут Артифактори делает??
@Configuration
public class JekaConfig {
@Bean @JekaQualifier
public List<String> messages() {
ArrayList<String> strings = new ArrayList<>
strings.add("Groovy");
strings.add("Spring");
return strings;
}
}
@Service
public class JekaService {
@Autowired @JekaQualifier
private List<String> list;
1. Groovy, Spring
2. Groovy, Spring, Artifactory
@Configuration
public class BaruchConfig {
@Bean @BaruchQualifier
public String str1() {return "Groovy";}
@Bean @BaruchQualifier
public String str2() {return "Spring";}
@Bean @BaruchQualifier
public String str3() {return "Artifactory";}
}
@Service
public class BaruchService {
@Autowired @BaruchQualifier
private List<String> list;
Что теперь с листом Жеки?
3. Пусто
4. Exception
@Configuration
public class JekaConfig {
@Bean @JekaQualifier
public List<String> messages() {
ArrayList<String> strings = new ArrayList<>
strings.add("Groovy");
strings.add("Spring");
return strings;
}
}
@Service
public class JekaService {
@Autowired @JekaQualifier
private List<String> list;
@Configuration
public class BaruchConfig {
@Bean @BaruchQualifier
public String str1() {return "Groovy";}
@Bean @BaruchQualifier
public String str2() {return "Spring";}
@Bean @BaruchQualifier
public String str3() {return "Artifactory";}
}
@Service
public class BaruchService {
@Autowired @BaruchQualifier
private List<String> list;
Какой Exception и почему?
Как мы это чиним?
1. ArrayList<String> вместо List<String>?
2. S
3. Не надо делать бин, который лист. Работаем с квалифаером
@Autowired
@JekaQualifier
private List<List<String>> list;
@Retention(RUNTIME)
@Qualifier
public @interface Comedy{}
@Retention(RUNTIME)
@Qualifier
public @interface Action{}
@Retention(RUNTIME)
@Qualifier
public @interface Melodrama{}
@Retention(RUNTIME)
@Qualifier
@Comedy @Action @Melodrama
public @interface AnyGenre{}
public interface Actor {
void play();
}
@Component @Comedy
public class Jim implements Actor { }
@Component
public class Katy implements Actor { }
@Component @Melodrama
public class Julia implements Actor { }
@Component @AnyGenre
public class Chuck implements Actor { }
@Component @Action @Comedy
public class Stallone implements Actor { }
@Component @Action
public class Tobey implements Actor { }
@Service
public class Film {
@Autowired
@Comedy
@Action
private List<Actor> actors;
}
Что заинжектится в этот лист?
1. Jim, Tobey
2. Jim, Tobey, Stallone, Chuck
3. Chuck, Katy
4. Chuck, Stallone
5. Что то пойдёт не так
А как же я…
@Component @Comedy
public class Jim implements Actor { }
@Component
public class Katy implements Actor { }
@Component @Melodrama
public class Julia implements Actor { }
@Component @AnyGenre
public class Chuck implements Actor { }
@Component @Action @Comedy
public class Stallone implements Actor { }
@Component @Action
public class Tobey implements Actor { }
@Service
public class Film {
@Autowired
@Comedy
@Action
private List<Actor> actors;
}
Что заинжектится в этот лист?
1. Jim, Tobey
2. Jim, Tobey, Stallone, Chuck
3. Chuck, Katy
4. Chuck, Stallone
5. Что то пойдёт не так
Как мы это чиним?
• Пишем свою обработку квалифаера
Так всё таки напишем BPP?
Загадочный PropertyPlaceholder
@Service
public class SomeService {
@Value("${JAVA_HOME}")
private void init(String javaHome) {
System.out.println(javaHome);
}
}
@Configuration
public class Config {
@Bean
public PropertySourcesPlaceholderConfigurer configurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
Что будет?
1.Будет warning, но всё сработает, как надо
2.Ничего не будет напечатано
3.Какой-то хитрый Exception
4.Напечатается JAVA_HOME, а не его значение
Вот такой warning:
• WARNING: @Bean method Config.configurer is non-static and returns
an object assignable to Spring's BeanFactoryPostProcessor interface
И чо?
@Configuration
public class Config {
@Value("${JAVA_HOME}")
private String javaHome;
@PostConstruct
public void init(){
System.out.println("javaHome = " + javaHome);
}
@Bean
public PropertySourcesPlaceholderConfigurer configurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
1.Будет warning, но всё сработает, как надо
2.Ничего не будет напечатано
3.Какой-то хитрый Exception
4.Напечатается javaHome = null
Что будет?
Как мы это чиним?
• Добавляем static
Спринговый enum
Выглядит знакомо?
public enum MpiProtocolType implements Serializable{
MAP(2, 3, 23, 56),
PRN(4), SRI4SM(560),
FSM(550, 551), LTE(316),
GTP(4000, 4001, 4002, 1000),
ISUP(1100, 1101, 1102, 1103, 1104, 1105),
SIP(5000),
ALL(0);
private final Integer[] opcodes;
MpiProtocolType(Integer... opcodes) {
this.opcodes=opcodes;
}
public boolean isMyOpcode(int opcode) {
return Arrays.asList(opcodes).contains(opcode);
}
}
А давайте спрингом
@Component
public enum Gender {
MALE, FEMALE;
private String description;
@Autowired
public void init(DescriptionConf descriptionConf) throws Exception {
Class<? extends DescriptionConf> clazz = descriptionConf.getClass();
Field field = clazz.getField(this.name().toLowerCase());
description = (String) field.get(descriptionConf);
}
public String getDescription() {
return description;
}
}
Что будет?
A. Всё отлично заработает
B. NoSuchMethodException
C. В description-е будет null
D. Что-то другое
Failed to instantiate [enums.Gender]:
No default constructor found
А давайте спрингом@Component
public enum Gender {
MALE, FEMALE;
private String description;
Gender(){}
@Autowired
public void init(DescriptionConf descriptionConf) throws Exception {
Class<? extends DescriptionConf> clazz = descriptionConf.getClass();
Field field = clazz.getField(this.name().toLowerCase());
description = (String) field.get(descriptionConf);
}
public String getDescription() {
return description;
}
}
Что теперь?
A. Всё отлично заработает
B. NoSuchMethodException
C. В description-е будет null
D. Что-то другое
Failed to instantiate [enums.Gender]:
No default constructor found
Кто знает в чём проблема?
@Component
public enum Gender {
MALE, FEMALE;
private String description;
Gender(){}
@Autowired
public void init(DescriptionConf descriptionConf) throws Exception {
Class<? extends DescriptionConf> clazz = descriptionConf.getClass();
Field field = clazz.getField(this.name().toLowerCase());
description = (String) field.get(descriptionConf);
}
public String getDescription() {
return description;
}
}
Как мы это чиним?
• Нужен кастомный classloader – открываем им джиру
Singleton vs Prototypes
@Component
@Scope("prototype")
public class T800 {
@PostConstruct
public void init(){
System.out.println("Give me your clothes");
}
@PreDestroy
public void destroy(){
System.out.println("You are terminated");
}
}
@Component
@Scope("singleton")
public class T1000 {
@Autowired
private T800 t800;
@PostConstruct
public void init(){
System.out.println("Where is John Connor");
}
@PreDestroy
public void destroy(){
System.out.println("Страшные звуки");
}
}
context.close();
1.Всё
2.Только цитаты T1000
3.Give me your close / Where is Jonh Connor
4.Give me your close / Where is Jonh Connor / Страшные звуки
Что будет напечатано?
Кто знает почему не сработал
destroy method у T800?
Destroy methods не работают для прототипов
А если прописать destroy method в xml-e?
• Что изменится?
• Появится xml!
И даже warning-a не будет!
Сами разбирайтесь
Что надо сделать чтобы был Warning?
• Написать BeanFactoryPostProcessor?
Мы напишем BPP
Решаем проблемы перформенса
Где destroy method будет бежать асинхронно?
@Service
public class Тормоз {
@PreDestroy
public void всёЗакрыть(){
… медленный код
}
}
@Service
public class Тормоз {
@PreDestroy
@Async
public void всёЗакрыть(){
… медленный код
}
}
@Bean(destroyMethod = "всёЗакрыть")
<bean class="Тормоз" destroy-method="всёЗакрыть"/>
1.
2.
3.
4.
A. Во всех случаях
B. Ни в каком
C. Только 2, если не забыли @EnableAsync
D. 3 & 4
А мы этой фигнёй не
занимаемся
Как мы это чиним?
• Ну например…
@PreDestroy
public void всёЗакрыть(){
new Thread(new Runnable() {
@Override
public void run() {
… Очень медленный код
}
}).start();
}
ScreenSaver
Frame Scope / Color Scope
A. Singleton / Singleton
B. Singleton / Prototype
C. Prototype / Singleton
D. Prototype / Prototype
Все ответы не правильные
Смерть XML-у
ДЕВОЧКА, КОТОРАЯ ЛЮБИЛА XML
Битва фабрик
Где Integer будет prototype?
<bean id="integer"
class="factoryBeans.IntegerFactory"
scope="prototype"/>
public class IntegerFactory implements FactoryBean<Integer> {
private Random random = new Random();
@Override
public Integer getObject() throws Exception {
return random.nextInt(10);
}
@Override
public Class<?> getObjectType() {
return Integer.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
<bean id="integerFactory"
class="factoryBeans.IntegerFactory"
scope="prototype"/>
<bean id="integer"
class="java.lang.Integer"
scope="singleton"
factory-bean="integerFactory"
factory-method="getInt"/>
A. Только 1
B. Только 2
C. Оба
D. Ни один
1) 2)
Где integer будет prototype?
<bean id="integer"
class="factoryBeans.IntegerFactory"
scope="prototype"/>
public class IntegerFactory implements FactoryBean<Integer> {
private Random random = new Random();
@Override
public Integer getObject() throws Exception {
return random.nextInt(10);
}
@Override
public Class<?> getObjectType() {
return Integer.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
<bean id="integerFactory"
class="factoryBeans.IntegerFactory"
scope="prototype"/>
<bean id="integer"
class="java.lang.Integer"
scope="singleton"
factory-bean="integerFactory"
factory-method="getInt"/>
A. Только 1
B. Только 2
C. Оба
D. Ни один
1) 2)
И чо?
Попробуйте сделать scope session
<bean id="integer"
class="factoryBeans.IntegerFactory"
scope="???"/>
public class IntegerFactory implements FactoryBean<Integer> {
private Random random = new Random();
@Override
public Integer getObject() throws Exception {
return random.nextInt(10);
}
@Override
public Class<?> getObjectType() {
return Integer.class;
}
@Override
public boolean isSingleton() {
return ???;
}
}
1)
Попробуйте сделать scope session
<bean id="integer"
class="factoryBeans.IntegerFactory"
scope="session"/> //не забыть proxy-mode
public class IntegerFactory implements FactoryBean<Integer> {
private Random random = new Random();
@Override
public Integer getObject() throws Exception {
return random.nextInt(10);
}
@Override
public Class<?> getObjectType() {
return Integer.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
<bean id="integerFactory"
class="factoryBeans.IntegerFactory"
scope="singleton"/>
<bean id="integer"
class="java.lang.Integer"
factory-bean="integerFactory"
factory-method="getInt“
scope="session"/> //не забыть proxy-mode
1) 2)
Выводы
1. Спринг не идеален, но лучше ничего нет
2. Не бойтесь его чинить
3. Стройте свою платформу на спринге, не
ограничивайтесь тем, что он может сам
4. И главное :
Выводы
Аннотации – это добро!!!
Спасибо за призы
Luxoft
infopulse
Spring puzzlers 2

Spring puzzlers 2

  • 1.
    О себе • Пишуна джаве с 2001 • Преподаю джаву с 2003 • Консультирую с 2008 • Арихтектор с 2009 • Пилю стартап с 2014 • Техлид по биг дате с 2015 • Naya technologies c 2015
  • 2.
  • 3.
  • 4.
    public interface Утюг{ @PostConstruct void разогреваться(); } @Component public class СуперДуперУтюг implements Утюг { @Override public void разогреваться() { System.out.println("разогреваюсь"); } @PostConstruct @Autowired public void гретьВоду(Вода вода){ System.out.println(вода+" грейся..."); } } A. Вода грейся B. Вода грейся & Разогреваюсь @Component public class Вода { @Override public String toString() { return "вода"; } } C. Разогреваюсь D. Что то пойдёт не так Что будет?
  • 6.
    IllegalStateException • method annotationrequires a no-arg method: public void iLoveInterfaces.СуперДуперУтюг.гретьВоду
  • 7.
    Как чиним? • Убираем@Postconstruct с метода помеченного @Autowired @PostConstruct @Autowired public void гретьВоду(Вода вода){ System.out.println(вода+" грейся..."); }
  • 8.
    public interface Утюг{ @PostConstruct void разогреваться(); } @Component public class СуперДуперУтюг implements Утюг { @Override public void разогреваться() { System.out.println("разогреваюсь"); } @Autowired public void гретьВоду(Вода вода){ System.out.println(вода+" грейся..."); } } A. Вода грейся B. Вода грейся & Разогреваюсь @Component public class Вода { @Override public String toString() { return "вода"; } } C. Разогреваюсь D. Вообще ничего не напечатается Что будет?
  • 9.
  • 10.
    public interface Утюг{ @PostConstruct void разогреваться(); } @Component public class СуперДуперУтюг implements Утюг { @Override public void разогреваться() { System.out.println("разогреваюсь"); } @Autowired public void гретьВоду(Вода вода){ System.out.println(вода+" грейся..."); } } A. Вода грейся B. Вода грейся & Разогреваюсь @Component public class Вода { @Override public String toString() { return "вода"; } } C. Разогреваюсь D. Вообще ничего не напечатается Что будет?
  • 11.
  • 12.
  • 13.
    Достал уже сосвоими BeanPostProcessors
  • 14.
  • 15.
    Будем сегодня писатьBPP? • Напишем BeanFactoryPostProcessor
  • 16.
    Не будем повторятьошибки Спринга • Это не правильно, что за Postconstruct отвечает BPP
  • 17.
    BeanDefinition – этоинтерфейс • AbstractBeanDefinition • AnnotatedBeanDefinition • ConfigurationClassBeanDefinition • GenericBeanDefinition • ScannedGenericBeanDefinition
  • 18.
    BeanDefinition – этоинтерфейс • AnnotatedBeanDefinition • AbstractBeanDefinition • ConfigurationClassBeanDefinition • GenericBeanDefinition • ScannedGenericBeanDefinition
  • 19.
    • AbstractBeanDefinition • AnnotatedBeanDefinition •ConfigurationClassBeanDefinition • GenericBeanDefinition • ScannedGenericBeanDefinition Та не…
  • 20.
    • AnnotatedBeanDefinition • AbstractBeanDefinition •ConfigurationClassBeanDefinition • GenericBeanDefinition • ScannedGenericBeanDefinition Хрен тебе
  • 21.
    class ConfigurationClassBeanDefinitionReader { } privatestatic class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition Package friendly
  • 22.
    Когда не получаетсязакастить по хорошему…
  • 23.
    Пошли ковырять то,что спрятано
  • 24.
    Сага о двухпрограммистах
  • 25.
    @Configuration public class BaruchConfig{ @Bean public String str1() {return "Groovy";} @Bean public String str2() {return "Spring";} } @Configuration public class JekaConfig { @Bean public List<String> messages() { ArrayList<String> strings = new ArrayList<>(); strings.add("Groovy"); strings.add("Spring"); return strings; } } @Service public class BaruchService { @Autowired private List<String> list; @Service public class JekaService { @Autowired private List<String> list; Что заинжектится в лист? 1. Groovy, Spring, Groovy, Spring 2. Groovy, Spring 3. Groovy, Spring, [Groovy, Spring] 4. Exception
  • 26.
    А в чёмтут был паззлер?
  • 27.
  • 28.
    Пока Жека дровне наломал я подстрахуюсь @Configuration public class BaruchConfig { @Bean @BaruchQualifier public String str1() {return "Groovy";} @Bean @BaruchQualifier public String str2() {return "Spring";} } @Service public class BaruchService { @Autowired @BaruchQualifier private List<String> list;
  • 29.
    @Configuration public class JekaConfig{ @Bean public List<String> messages() { ArrayList<String> strings = new ArrayList<>(); strings.add("Groovy"); strings.add("Spring"); return strings; } } @Service public class JekaService { @Autowired private List<String> list; 1. У Баруха всё хорошо 2. У Жеки всё хорошо 3. У нас обоих всё хорошо 4. У нас обоих всё плохо @Configuration public class BaruchConfig { @Bean @BaruchQualifier public String str1() {return "Groovy";} @Bean @BaruchQualifier public String str2() {return "Spring";} } @Service public class BaruchService { @Autowired @BaruchQualifier private List<String> list; Что теперь будет?
  • 30.
    Ну когда ужебудет паззлер?
  • 31.
    А теперь можнодобавить Артифактори
  • 32.
    @Configuration public class JekaConfig{ @Bean public List<String> messages() { ArrayList<String> strings = new ArrayList<>(); strings.add("Groovy"); strings.add("Spring"); return strings; } } @Service public class JekaService { @Autowired private List<String> list; Да Нет @Configuration public class BaruchConfig { @Bean @BaruchQualifier public String str1() {return "Groovy";} @Bean @BaruchQualifier public String str2() {return "Spring";} @Bean @BaruchQualifier public String str3() {return "Artifactory";} } @Service public class BaruchService { @Autowired @BaruchQualifier private List<String> list; Повлияет ли это на лист Жеки?
  • 33.
    Какого хрена тутАртифактори делает??
  • 34.
    @Configuration public class JekaConfig{ @Bean @JekaQualifier public List<String> messages() { ArrayList<String> strings = new ArrayList<> strings.add("Groovy"); strings.add("Spring"); return strings; } } @Service public class JekaService { @Autowired @JekaQualifier private List<String> list; 1. Groovy, Spring 2. Groovy, Spring, Artifactory @Configuration public class BaruchConfig { @Bean @BaruchQualifier public String str1() {return "Groovy";} @Bean @BaruchQualifier public String str2() {return "Spring";} @Bean @BaruchQualifier public String str3() {return "Artifactory";} } @Service public class BaruchService { @Autowired @BaruchQualifier private List<String> list; Что теперь с листом Жеки? 3. Пусто 4. Exception
  • 36.
    @Configuration public class JekaConfig{ @Bean @JekaQualifier public List<String> messages() { ArrayList<String> strings = new ArrayList<> strings.add("Groovy"); strings.add("Spring"); return strings; } } @Service public class JekaService { @Autowired @JekaQualifier private List<String> list; @Configuration public class BaruchConfig { @Bean @BaruchQualifier public String str1() {return "Groovy";} @Bean @BaruchQualifier public String str2() {return "Spring";} @Bean @BaruchQualifier public String str3() {return "Artifactory";} } @Service public class BaruchService { @Autowired @BaruchQualifier private List<String> list; Какой Exception и почему?
  • 37.
    Как мы эточиним? 1. ArrayList<String> вместо List<String>? 2. S 3. Не надо делать бин, который лист. Работаем с квалифаером @Autowired @JekaQualifier private List<List<String>> list;
  • 40.
    @Retention(RUNTIME) @Qualifier public @interface Comedy{} @Retention(RUNTIME) @Qualifier public@interface Action{} @Retention(RUNTIME) @Qualifier public @interface Melodrama{} @Retention(RUNTIME) @Qualifier @Comedy @Action @Melodrama public @interface AnyGenre{} public interface Actor { void play(); }
  • 41.
    @Component @Comedy public classJim implements Actor { } @Component public class Katy implements Actor { } @Component @Melodrama public class Julia implements Actor { } @Component @AnyGenre public class Chuck implements Actor { } @Component @Action @Comedy public class Stallone implements Actor { } @Component @Action public class Tobey implements Actor { } @Service public class Film { @Autowired @Comedy @Action private List<Actor> actors; } Что заинжектится в этот лист? 1. Jim, Tobey 2. Jim, Tobey, Stallone, Chuck 3. Chuck, Katy 4. Chuck, Stallone 5. Что то пойдёт не так
  • 42.
  • 43.
    @Component @Comedy public classJim implements Actor { } @Component public class Katy implements Actor { } @Component @Melodrama public class Julia implements Actor { } @Component @AnyGenre public class Chuck implements Actor { } @Component @Action @Comedy public class Stallone implements Actor { } @Component @Action public class Tobey implements Actor { } @Service public class Film { @Autowired @Comedy @Action private List<Actor> actors; } Что заинжектится в этот лист? 1. Jim, Tobey 2. Jim, Tobey, Stallone, Chuck 3. Chuck, Katy 4. Chuck, Stallone 5. Что то пойдёт не так
  • 44.
    Как мы эточиним? • Пишем свою обработку квалифаера
  • 45.
    Так всё такинапишем BPP?
  • 46.
    Загадочный PropertyPlaceholder @Service public classSomeService { @Value("${JAVA_HOME}") private void init(String javaHome) { System.out.println(javaHome); } } @Configuration public class Config { @Bean public PropertySourcesPlaceholderConfigurer configurer(){ return new PropertySourcesPlaceholderConfigurer(); } } Что будет? 1.Будет warning, но всё сработает, как надо 2.Ничего не будет напечатано 3.Какой-то хитрый Exception 4.Напечатается JAVA_HOME, а не его значение
  • 47.
    Вот такой warning: •WARNING: @Bean method Config.configurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface И чо?
  • 48.
    @Configuration public class Config{ @Value("${JAVA_HOME}") private String javaHome; @PostConstruct public void init(){ System.out.println("javaHome = " + javaHome); } @Bean public PropertySourcesPlaceholderConfigurer configurer(){ return new PropertySourcesPlaceholderConfigurer(); } } 1.Будет warning, но всё сработает, как надо 2.Ничего не будет напечатано 3.Какой-то хитрый Exception 4.Напечатается javaHome = null Что будет?
  • 49.
    Как мы эточиним? • Добавляем static
  • 50.
  • 51.
    Выглядит знакомо? public enumMpiProtocolType implements Serializable{ MAP(2, 3, 23, 56), PRN(4), SRI4SM(560), FSM(550, 551), LTE(316), GTP(4000, 4001, 4002, 1000), ISUP(1100, 1101, 1102, 1103, 1104, 1105), SIP(5000), ALL(0); private final Integer[] opcodes; MpiProtocolType(Integer... opcodes) { this.opcodes=opcodes; } public boolean isMyOpcode(int opcode) { return Arrays.asList(opcodes).contains(opcode); } }
  • 52.
    А давайте спрингом @Component publicenum Gender { MALE, FEMALE; private String description; @Autowired public void init(DescriptionConf descriptionConf) throws Exception { Class<? extends DescriptionConf> clazz = descriptionConf.getClass(); Field field = clazz.getField(this.name().toLowerCase()); description = (String) field.get(descriptionConf); } public String getDescription() { return description; } } Что будет? A. Всё отлично заработает B. NoSuchMethodException C. В description-е будет null D. Что-то другое
  • 53.
    Failed to instantiate[enums.Gender]: No default constructor found
  • 54.
    А давайте спрингом@Component publicenum Gender { MALE, FEMALE; private String description; Gender(){} @Autowired public void init(DescriptionConf descriptionConf) throws Exception { Class<? extends DescriptionConf> clazz = descriptionConf.getClass(); Field field = clazz.getField(this.name().toLowerCase()); description = (String) field.get(descriptionConf); } public String getDescription() { return description; } } Что теперь? A. Всё отлично заработает B. NoSuchMethodException C. В description-е будет null D. Что-то другое
  • 55.
    Failed to instantiate[enums.Gender]: No default constructor found
  • 56.
    Кто знает вчём проблема? @Component public enum Gender { MALE, FEMALE; private String description; Gender(){} @Autowired public void init(DescriptionConf descriptionConf) throws Exception { Class<? extends DescriptionConf> clazz = descriptionConf.getClass(); Field field = clazz.getField(this.name().toLowerCase()); description = (String) field.get(descriptionConf); } public String getDescription() { return description; } }
  • 57.
    Как мы эточиним? • Нужен кастомный classloader – открываем им джиру
  • 58.
  • 59.
    @Component @Scope("prototype") public class T800{ @PostConstruct public void init(){ System.out.println("Give me your clothes"); } @PreDestroy public void destroy(){ System.out.println("You are terminated"); } } @Component @Scope("singleton") public class T1000 { @Autowired private T800 t800; @PostConstruct public void init(){ System.out.println("Where is John Connor"); } @PreDestroy public void destroy(){ System.out.println("Страшные звуки"); } } context.close(); 1.Всё 2.Только цитаты T1000 3.Give me your close / Where is Jonh Connor 4.Give me your close / Where is Jonh Connor / Страшные звуки Что будет напечатано?
  • 61.
    Кто знает почемуне сработал destroy method у T800?
  • 62.
    Destroy methods неработают для прототипов
  • 63.
    А если прописатьdestroy method в xml-e? • Что изменится? • Появится xml!
  • 64.
    И даже warning-aне будет! Сами разбирайтесь
  • 65.
    Что надо сделатьчтобы был Warning? • Написать BeanFactoryPostProcessor?
  • 67.
  • 68.
  • 69.
    Где destroy methodбудет бежать асинхронно? @Service public class Тормоз { @PreDestroy public void всёЗакрыть(){ … медленный код } } @Service public class Тормоз { @PreDestroy @Async public void всёЗакрыть(){ … медленный код } } @Bean(destroyMethod = "всёЗакрыть") <bean class="Тормоз" destroy-method="всёЗакрыть"/> 1. 2. 3. 4. A. Во всех случаях B. Ни в каком C. Только 2, если не забыли @EnableAsync D. 3 & 4
  • 70.
    А мы этойфигнёй не занимаемся
  • 71.
    Как мы эточиним? • Ну например… @PreDestroy public void всёЗакрыть(){ new Thread(new Runnable() { @Override public void run() { … Очень медленный код } }).start(); }
  • 72.
  • 73.
    Frame Scope /Color Scope A. Singleton / Singleton B. Singleton / Prototype C. Prototype / Singleton D. Prototype / Prototype
  • 74.
    Все ответы неправильные
  • 75.
  • 76.
  • 77.
  • 78.
    Где Integer будетprototype? <bean id="integer" class="factoryBeans.IntegerFactory" scope="prototype"/> public class IntegerFactory implements FactoryBean<Integer> { private Random random = new Random(); @Override public Integer getObject() throws Exception { return random.nextInt(10); } @Override public Class<?> getObjectType() { return Integer.class; } @Override public boolean isSingleton() { return true; } } <bean id="integerFactory" class="factoryBeans.IntegerFactory" scope="prototype"/> <bean id="integer" class="java.lang.Integer" scope="singleton" factory-bean="integerFactory" factory-method="getInt"/> A. Только 1 B. Только 2 C. Оба D. Ни один 1) 2)
  • 80.
    Где integer будетprototype? <bean id="integer" class="factoryBeans.IntegerFactory" scope="prototype"/> public class IntegerFactory implements FactoryBean<Integer> { private Random random = new Random(); @Override public Integer getObject() throws Exception { return random.nextInt(10); } @Override public Class<?> getObjectType() { return Integer.class; } @Override public boolean isSingleton() { return true; } } <bean id="integerFactory" class="factoryBeans.IntegerFactory" scope="prototype"/> <bean id="integer" class="java.lang.Integer" scope="singleton" factory-bean="integerFactory" factory-method="getInt"/> A. Только 1 B. Только 2 C. Оба D. Ни один 1) 2)
  • 81.
  • 82.
    Попробуйте сделать scopesession <bean id="integer" class="factoryBeans.IntegerFactory" scope="???"/> public class IntegerFactory implements FactoryBean<Integer> { private Random random = new Random(); @Override public Integer getObject() throws Exception { return random.nextInt(10); } @Override public Class<?> getObjectType() { return Integer.class; } @Override public boolean isSingleton() { return ???; } } 1)
  • 83.
    Попробуйте сделать scopesession <bean id="integer" class="factoryBeans.IntegerFactory" scope="session"/> //не забыть proxy-mode public class IntegerFactory implements FactoryBean<Integer> { private Random random = new Random(); @Override public Integer getObject() throws Exception { return random.nextInt(10); } @Override public Class<?> getObjectType() { return Integer.class; } @Override public boolean isSingleton() { return true; } } <bean id="integerFactory" class="factoryBeans.IntegerFactory" scope="singleton"/> <bean id="integer" class="java.lang.Integer" factory-bean="integerFactory" factory-method="getInt“ scope="session"/> //не забыть proxy-mode 1) 2)
  • 84.
    Выводы 1. Спринг неидеален, но лучше ничего нет 2. Не бойтесь его чинить 3. Стройте свою платформу на спринге, не ограничивайтесь тем, что он может сам 4. И главное :
  • 85.
  • 86.