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

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

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
Spring. Инжектить бины с разным скоупом друг в друга.
    #39085878
no56892
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
потому, что:
Код: java
1.
validatorHolder21 == validatorHolder22


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


?

конечно true.

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

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

Код: 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
Spring. Инжектить бины с разным скоупом друг в друга.
    #39085922
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
судя по статье можно как-то и через
Код: xml
1.
<aop:scoped-proxy/>

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

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

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

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

Что там пишут в статьях не читал. У Спринга такая документация, что статей и не надо. Ответы на все вопросы всегда находил там.
...
Рейтинг: 0 / 0
Spring. Инжектить бины с разным скоупом друг в друга.
    #39085977
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и про <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
Spring. Инжектить бины с разным скоупом друг в друга.
    #39086012
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexander A. Sak,

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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



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


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