Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring. Инжектить бины с разным скоупом друг в друга. / 25 сообщений из 30, страница 1 из 2
25.10.2015, 17:00
    #39085861
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Вопрос навеян походом на собеседование.

Собственно нагуглил такую вот статью

https://prasanthnath.wordpress.com/2013/03/21/injecting-a-prototype-bean-into-a-singleton-bean/

пробую воспроизвести. Написал hello world

код:

Код: java
1.
2.
public class MyValidator {
}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public class ValidatorHolder {
    
    MyValidator myValidator;

    public MyValidator getMyValidator() {
        return myValidator;
    }

    public void setMyValidator(MyValidator myValidator) {
    }
}



конфиг:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
   <bean id="validatorHolder" class="com.example.domain.ValidatorHolder">
        <property name="myValidator" ref="validator"/>
    </bean>

    <bean id="validator" scope="prototype" class="com.example.domain.MyValidator">
        <!-- This instructs the container to proxy the current bean-->
        <aop:scoped-proxy/>
    </bean>



main:

Код: java
1.
2.
3.
4.
5.
        ApplicationContext xmlContext = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
        ValidatorHolder validatorHolder21 = (ValidatorHolder) xmlContext.getBean("validatorHolder");
        ValidatorHolder validatorHolder22 = (ValidatorHolder) xmlContext.getBean("validatorHolder");
        
        System.out.println(validatorHolder21.getMyValidator() == validatorHolder22.getMyValidator());



Почему всё равно true?

я не понял о чем в статье написано?
...
Рейтинг: 0 / 0
25.10.2015, 17:24
    #39085878
no56892
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
потому, что:
Код: java
1.
validatorHolder21 == validatorHolder22


?
...
Рейтинг: 0 / 0
25.10.2015, 17:52
    #39085917
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
no56892потому, что:
Код: java
1.
validatorHolder21 == validatorHolder22


?

конечно true.

singleton же
...
Рейтинг: 0 / 0
25.10.2015, 17:54
    #39085920
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
НО

при конфигурации

Код: xml
1.
2.
3.
4.
5.
6.
7.
    <bean id="validatorHolder" class="com.example.domain.ValidatorHolder">
        <lookup-method name="getMyValidator" bean="validator"/>
    </bean>

    <bean id="validator" scope="prototype" class="com.example.domain.MyValidator">
        <!-- This instructs the container to proxy the current bean-->
    </bean>



и немного меняем код бина:

Код: java
1.
2.
3.
4.
5.
6.
public abstract class ValidatorHolder {

 
    public abstract MyValidator getMyValidator();

}




будет false
...
Рейтинг: 0 / 0
25.10.2015, 17:55
    #39085922
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
судя по статье можно как-то и через
Код: xml
1.
<aop:scoped-proxy/>

но они много оставляют за кадром. Мне не понятно как это сделать.
...
Рейтинг: 0 / 0
25.10.2015, 18:07
    #39085931
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
вот то же самое пишут

http://www.java-allandsundry.com/2012/08/spring-scoped-proxy.html

но блин... не работает
...
Рейтинг: 0 / 0
25.10.2015, 18:29
    #39085952
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Тут же все просто. Надо представить себя контейнером Spring и в точности выполнить то, что описано конфигом.

В первом случае экземпляр com.example.domain.ValidatorHolder создается один раз. Поле myValidator заполняется один раз, поэтому то, что getMyValidator() всегда возвращает одно и тоже, удивлять не должно. То, что там добавили aop:scoped-proxy -- да какая разница? Экземпляр создавали один раз, myValidator заполняли один раз, какое время жизни предполагалось у того MyValidator уже не важно. Он теперь в синглтоне.
...
Рейтинг: 0 / 0
25.10.2015, 18:36
    #39085958
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Во втором случае мы подменяем метод getMyValidator. Подмененный метод уже возвращает не поле, а бин из контейнера. Вот тут уже время жизни бина имеет значение. Мы же теперь фактически каждый раз в getMyValidator() делаем xmlContext.getBean("validator").

Что там пишут в статьях не читал. У Спринга такая документация, что статей и не надо. Ответы на все вопросы всегда находил там.
...
Рейтинг: 0 / 0
25.10.2015, 18:54
    #39085977
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Ну и про <aop:scoped-proxy>.
Отличие будет заметно, если у MyValidator сделать свойство гарантированно разное у разных экземпляров. Как-то так:
Код: java
1.
2.
3.
4.
5.
6.
public class MyValidator {
   Object prop = new Object();
   public Object getProp() {
      return prop;
   }
}



Вот тут будет сюрприз:
Код: java
1.
2.
validatorHolder21.getMyValidator() == validatorHolder22.getMyValidator(); // Это true
validatorHolder21.getMyValidator().getProp() == validatorHolder22.getMyValidator().getProp(); // А это false


будет false.

Подозреваю, из-за того, что <aop:scoped-proxy> указан у бина со scope="prototype", даже такое:
Код: java
1.
validatorHolder21.getMyValidator().getProp() == validatorHolder21.getMyValidator().getProp()


будет false.

Это я сейчас как Spring-контейнер написал. Ничего не проверял. Как-никак 21:50 воскресенья.
...
Рейтинг: 0 / 0
25.10.2015, 19:36
    #39086012
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Alexander A. Sak,

да, всё верно.

Но я что-то концепцию aop-proxy не осознал.

Можете чуть детальнее почему 2 объекта указывают на один и тот же бин, но при этом у них разный prop
...
Рейтинг: 0 / 0
25.10.2015, 20:47
    #39086137
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Alexander A. Sak,

Я чего-то не могу понять, неужели без этой аннотации не прокси будет подставлен?
...
Рейтинг: 0 / 0
26.10.2015, 00:49
    #39086293
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Наверное чтобы это понять мне надо понять как происходит процесс инжектинга для прокси.
Для сеттер инжектинга всё понятно. Контейнер вызывает конструктор для бина, который надо инстанциировать. Затем через сеттеры инжектит зависимости. а для прокси вообще не очень понятно.

Можно наверное отнаследоваться от класса, который надо инстанциировать... видимо через рефлекшн сможем добраться до приватного поля. таким образом получили наследника, у которого есть сеттеры.


Но вроде как по этой логике каждому бину будет соответствовать своя прокся...у меня не так получилось
...
Рейтинг: 0 / 0
26.10.2015, 13:48
    #39086813
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Up
...
Рейтинг: 0 / 0
26.10.2015, 13:50
    #39086817
Atum1
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
полено будет посмотреть , чтобы не задави на собеседовании - будете знать ответ :
YouTube Video
...
Рейтинг: 0 / 0
26.10.2015, 21:49
    #39087416
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Atum1,

Он про look up method только рассказал. Это мне очевидно и понятно.

С прокси непонятно.
...
Рейтинг: 0 / 0
26.10.2015, 22:01
    #39087422
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Ну хотя таргет класс это наверное то есть...но это не отвечает на мои вопросы
...
Рейтинг: 0 / 0
27.10.2015, 10:24
    #39087682
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
questionerНаверное чтобы это понять мне надо понять как происходит процесс инжектинга для прокси.
Для сеттер инжектинга всё понятно. Контейнер вызывает конструктор для бина, который надо инстанциировать. Затем через сеттеры инжектит зависимости. а для прокси вообще не очень понятно.
Можно наверное отнаследоваться от класса, который надо инстанциировать... видимо через рефлекшн сможем добраться до приватного поля. таким образом получили наследника, у которого есть сеттеры.
Но вроде как по этой логике каждому бину будет соответствовать своя прокся...у меня не так получилось

В свойство вместо настоящего бина инъектируется прокси. Когда происходит обращение к этой прокси, то Spring может найти подходящий экземпляр соответствующий scope и делегировать вызов ему. Таким образом scope вызываемого бина может отличаться от вызывающего.
...
Рейтинг: 0 / 0
27.10.2015, 10:41
    #39087713
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Blazkowicz,
Я тоже так понял -
BlazkowiczКогда происходит обращение к этой прокси, то Spring может найти подходящий экземпляр соответствующий scope и делегировать вызов ему

Объясните, пожалуйста тогда почему

авторvalidatorHolder21.getMyValidator() == validatorHolder21.getMyValidator(); // Это true
validatorHolder21.getMyValidator().getProp() == validatorHolder21.getMyValidator().getProp(); // А это false

ведь каждый раз при обращении к проксЕ должна быть вызвана нужная прокся.

а вот если уже к методу прокси обращаться, то становится очевидно, что происходит обращение к новой проксЕ.
...
Рейтинг: 0 / 0
27.10.2015, 15:57
    #39088185
Atum1
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
questionerAtum1,

Он про look up method только рассказал. Это мне очевидно и понятно.

С прокси непонятно.

смотрите тогда оба видео внимательно там про все есть и про прокси так же ...

все ответы на все ваши вопросы.
...
Рейтинг: 0 / 0
27.10.2015, 18:58
    #39088369
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
questionerОбъясните, пожалуйста тогда почему

авторvalidatorHolder21.getMyValidator() == validatorHolder21.getMyValidator(); // Это true
validatorHolder21.getMyValidator().getProp() == validatorHolder21.getMyValidator().getProp(); // А это false

ведь каждый раз при обращении к проксЕ должна быть вызвана нужная прокся.

а вот если уже к методу прокси обращаться, то становится очевидно, что происходит обращение к новой проксЕ.

Потому что после указания <aop:scoped-proxy/> то, что возвращает getMyValidator(), уже не наш MyValidator, а другой объект с какими-то такими методами:

Код: java
1.
2.
3.
public Object getProp() {
   return appContext.getBean("validator").getProp();
}



Раз бин "validator" объявили scope="prototype", каждый вызов getProp() будет возвращать новый объект.

Кстати, в доке Спринга написано: You do not need to use the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or prototypes.
...
Рейтинг: 0 / 0
28.10.2015, 00:37
    #39088525
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Alexander A. Sak,

видео посмотрел, непонятки остались)
причём какие-то глобальные и фундаментальные


Код: java
1.
System.out.println(validatorHolder1.getMyValidator() == validatorHolder1.getMyValidator()); true



выводит:
Код: java
1.
2.
 System.out.println(validatorHolder1.getMyValidator());
        System.out.println(validatorHolder1.getMyValidator());


consolecom.example.domain.MyValidator@2462cb01
com
.example.domain.MyValidator@19b843ba


меня учили, что ссылки равны, если адрес в памяти один и тот же.


Чего за фигня?
...
Рейтинг: 0 / 0
28.10.2015, 00:50
    #39088530
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
[quot Alexander A. Sak]
Потому что после указания <aop:scoped-proxy/> то, что возвращает getMyValidator(), уже не наш MyValidator, а другой объект с какими-то такими методами:
/quot]

так почему getMyValidator() возвращает одну и ту же (на ==) прокси.

Но вызов каждого метода на этой прокси уникален
...
Рейтинг: 0 / 0
29.10.2015, 16:34
    #39090291
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
up
...
Рейтинг: 0 / 0
16.11.2015, 00:45
    #39104022
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
Atum1полено будет посмотреть , чтобы не задави на собеседовании - будете знать ответ :
YouTube Video
...
Рейтинг: 0 / 0
16.11.2015, 09:28
    #39104113
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring. Инжектить бины с разным скоупом друг в друга.
questioner
Код: java
1.
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)



Сказал, что плохо, что нечто создаётся каждый раз. Что именно создаётся каждый раз я так и не понял.
На какой минуте об этом речь?
Scope=prototype знаем вообще?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring. Инжектить бины с разным скоупом друг в друга. / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]