Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Scope("prototype") не работает: в Set-свойство род-ля добавляет 5 раз один и тот же detail / 2 сообщений из 2, страница 1 из 1
28.11.2014, 21:09
    #38820016
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Scope("prototype") не работает: в Set-свойство род-ля добавляет 5 раз один и тот же detail
Здравствуйте.

Есть вот такой parent-detail.xml:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">

  <context:annotation-config/>
 
  <bean id="detail" class="Detail" />
  <!-- <bean id="detail" class="Detail" scope="prototype" /> -->
  <bean id="parent" class="Parent"/>

</beans>



И следующие классы для проверки:
Код: java
1.
2.
3.
4.
5.
6.
7.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class Detail {

}


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
import java.util.*;
import javax.inject.*;

public class Parent {
  private Set<Detail> details;

  public Set<Detail> getdetails() {
	    return details;
  }

  @Inject
  //@Named("detail")
  public Parent( Provider<Detail> p ) {
	  details = new HashSet<Detail>();
	  for(int i=0; i<5; i++)  {
		  details.add( p.get() );
      }
      System.out.println("Created "+this.getClass().getName()+" with details="+details+" of size="+details.size() );
      System.out.println("Details:");
      for(Detail k : details) {
        System.out.println(k);
	  }
  }

}


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestParentDetail {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext cx = new ClassPathXmlApplicationContext("parent-detail.xml");

	Parent p1 = (Parent) cx.getBean("parent");

        System.out.println("Done.");
    }
}



Если это всё откомпилять и запустить, то будет видно, что в свойство parent.details добавился hashset только из одного элемента:

Код: plaintext
1.
2.
3.
4.
5.
6.
Output:

Created Parent with details=[Detail@a00185] of size=1
Details:
Detail@a00185
Done.

Если же в XML'e закомментарить "<bean id="detail" class="Detail" />" и раскомментарить "<bean id="detail" class="Detail" scope="prototype" />", то будет всё ОК:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Created Parent with details=[Detail@121177e, Detail@a00185, Detail@1a4ded3, Detail@1328c7a, Detail@1989b5] of size=5
Details:
Detail@121177e
Detail@a00185
Detail@1a4ded3
Detail@1328c7a
Detail@1989b5
Done.

Что не хватает в исходном варианте, чтобы он добавлял в набор деталек не по принципу singleton'а, а как запрашивается - т.е. на каждый вызов details.add( p.get() ) чтобы был добален новый инстанс ?
...
Рейтинг: 0 / 0
28.11.2014, 23:28
    #38820103
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Scope("prototype") не работает: в Set-свойство род-ля добавляет 5 раз один и тот же detail
Разобрался, кажись.

Надо было:
1) обязательно засунуть все классы в пакет;
2) поменять context:annotation-config на context:component-scan.

В итоге, вот работающий вариант:
java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
package testComponentScan;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class Detail {

}

//////////////////////////////////////

package testComponentScan;
import java.util.*;
import javax.inject.*;

import org.springframework.context.annotation.Scope;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Parent {
  private Set<Detail> details;

  public Set<Detail> getdetails() {
	    return details;
  }

  @Inject
  public Parent( Provider<Detail> p ) {
	  details = new HashSet<Detail>();
	  for(int i=0; i<5; i++)  {
		  details.add( p.get() );
      }
      System.out.println("Created "+this.getClass().getName()+" with details="+details+" of size="+details.size() );
      System.out.println("Details:");
      for(Detail k : details) {
        System.out.println(k);
	  }
  }

}

///////////////////////////////

package testComponentScan;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestParentDetail {
    private static final String XML_FILE = "parent-detail-component-scan.xml";
    //private static final String XML_FILE = "parent-detail-annotation-config.xml";
    public static void main(String[] args) throws Exception {
        System.out.println("Use XML_FILE="+XML_FILE);
        ClassPathXmlApplicationContext cx = new ClassPathXmlApplicationContext(XML_FILE);

	Parent p1 = (Parent) cx.getBean("parent");
        System.out.println("Done.");
    }
}

XML "parent-detail-component-scan.xml"
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="
	http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">

  <context:component-scan
    base-package="testComponentScan">
  </context:component-scan>  

</beans>


PS. Не понял причину, но "import javax.inject.*;" не прокатит, если не указать при компиляции в classpath каталог, где есть какой-нить javaee.jar; у мну оказался глассфишный, с ним компиляция прокатила. Странно.

PPS. Как этому context:comp-scan'у задать пакет "по-умолчанию", т.е. когда классы не в пакете ? Вот такое: base-package="" - компилирует, но на самом деле не работает. (да, я знаю, что всё надо раскладывать по пакетам; просто интересно стало, можно ли вообще сделать это без них :))
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Scope("prototype") не работает: в Set-свойство род-ля добавляет 5 раз один и тот же detail / 2 сообщений из 2, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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