Spring - jak zrobić automatyczne wiązanie po konstruktorze adnotacjami?

0

Mam klasę User:

http://pastebin.com/cZM0U1jm

i do niej UserRepository:

http://pastebin.com/xh3HRB7R

całość zbiera w kupę Main:

      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
     
      UserRepository obj = (UserRepository)context.getBean("repozytoriumUzytkownikow");
      obj.printUser1();
      obj.printUser2(); 

xml:

<bean id="user1"
		class="database.model.User">
		<constructor-arg value="100"/>
		<constructor-arg value="springa"/>
		<constructor-arg value="springa"/>
		<constructor-arg value="springa"/>
		<constructor-arg value="1"/>
	</bean>
	
	<bean id="user2"
		class="database.model.User">
		<constructor-arg value="101"/>
		<constructor-arg value="springu"/>
		<constructor-arg value="springu"/>
		<constructor-arg value="springu"/>
		<constructor-arg value="0"/>
	</bean>	 
	
	<bean id="repozytoriumUzytkownikow" class="database.model.UserRepository"
		autowire="byName">		
   </bean> 

Moje pytanie brzmi- jak mam to przerobić żeby działało to na adnotacjach? Chcę zrobić automatyczne wiązanie po konstruktorze. Wstawiłem @Service przed nazwy klas, zmodyfikowałem xml-a, a nad konstuktor User wrzuciłem @Autowired. Nie działa i nie mam pojęcia jak to powinno być. Przepracowałem tutorial Artura Owczarka, ale o ile jeszcze o konfiguracji w xml-u cokolwiek się dowiedziałem, to na podstawie zrealizowanych w tutorialu przykładów jakoś kompletnie nie kumam @. Więc jeśli to by nie było problemem, proszę także o podanie sensownych tutoriali ze Springa, które Wam pomogły.

0

@Lukasz_ dodałem w namespaces context i resztę podmieniłem na:

   <!-- Springu, bede uzywal annotacji! -->
   <context:annotation-config/>
   
   <!-- Skanuj pakiet database.model -->
   <context:component-scan base-package="database.model.*"/> 
0
  1. @Named i @Inject, idźmy z duchem czasu...
  2. Wstrzykuj przez pola nie konstruktor :P
  3. User generalnie nie wygląda na klasę która powinna być beanem, ale jak tam sobie chcesz. Niemniej zauważ że skądś konstruktor usera w takim razie musi brać wartości więc musisz tam wiązać jakieś @Value na przykład.
  4. Pokaż kod który nie działa i jakie masz błędy bo inaczej to możemy tylko zgadywać co zmodyfikowałeś. Co to w ogóle za pomysł pokazać działający kod, napisać że "cośtam zmieniłem" i pytać czemu nie działa...
0

Zrezygnowałem z konfiguracji w xml-u, wprowadziłem parę zmian i udało się zlikwidować error;). Zamiast niego w konsoli wyświetlają się nulle, więc jesteśmy ciut bliżej;)

User:

http://pastebin.com/1aQ72qis

UserRepository: ( z odkomentowanymi częściami wynik jest ten sam)

http://pastebin.com/ZZ5rgktN

Main:

      ApplicationContext ctx = 
   		   new AnnotationConfigApplicationContext(UserRepository.class);
      
      UserRepository obj = (UserRepository)ctx.getBean("userRepository");  
      obj.printUser1();
      obj.printUser2();

Konsola:

user1 : null
user2 : null


@Shalom

  1. Ok, dowiem się co robią te annotacje
  2. Możesz wytłumaczyć dlaczego? Taki konstruktor jest potrzebny w tej klasie
  3. Możesz wytłumaczyć dlaczego?
    4
0

No teraz to nic nie wstrzykujesz to sie nie dziw że jest null :P Daj @Inject nad tymi userami w UserRepository...
2. Jeśli tworzysz ten obiekt tylko przez springa to wcale nie jest potrzebny ;) Jeśli tworzysz te obiekty także ręcznie to tworzenie ich jednocześnie jako springowych beanów to jakis WTF.
3. Bo nie wszystkie klasy powinny być beanami! Ta klasa user wygląda na jakieś standardowe bezstanowe immutable DTO i nijak nie nadaje się na beana bo to by było nielogiczne.

0

Mój eclipse nie rozpoznaje @Inject. Dałem nad userami w **UserRepository **:

@Service("userRepository")
public class UserRepository {
	@Autowired(required = false)
	private User user1;
	@Autowired(required = false)
	private User user2;
//setery, getery, printUser2

..bo bez requiereda konsola wywala:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private database.model.User database.model.UserRepository.user1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [database.model.User] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

i przy okazji wrzucę User:

@Component
public class User {
	private int id;
	private String login;
	private String password;
	private String username;
	private int privileges;
		

	/*******************
	***** C-TOR *****
	******************/	
	public User(int id, String login, String password, String username, int privileges) {
		this.id = id;
		this.login = login;
		this.password = password;
		this.username = username;
		this.privileges = privileges; //different than 0 if admin
	}
	
	@Bean
	public User user1(){
		return new User(1, "l", "p", "u", 1);
	}
	@Bean
	public User user2(){
		return new User(2, "l", "p", "u", 0);
	}
//....

i w dalszym ciągu są nulle

0
KapitanZ napisał(a):

Mój eclipse nie rozpoznaje @Inject

Zależność musisz dodać:

dependency>
	<groupId>javax.inject</groupId>
	<artifactId>javax.inject</artifactId>
	<version>ktoras tam wersja</version>
</dependency>
0

Teraz to znów WTF jakiś. @Bean to adnotacja która powinna być w KONFIGURACJI a nie w klasie która ma być beanem. Co nadal wynika z tego że próbujesz zrobić bean z czegoś co nie powinno nim być.

1

Dobra od początku. Zacznij od zwykłego wstrzykiwania. Nad polami typu "User" w klasie "User repository" wklepujesz adnotację @Inject. Dlaczego ? Ponieważ mówi ona Springowi (nie tylko, jest dość uniwersalna), że powinien rozejrzeć się w skanowanym pakiecie i dobrać sobie obiekt zgodnie z typem jaki tu jest. Czyli poszuka i znajdzie User. Musisz także oznaczyć klasę "User" adnotacją @named aby Spring przy skanowaniu pakietów uwzględnił ją jako coś co może być wstrzyknięte. W configu potrzebujesz tylko włączenia sterowania adnotacjami. Musisz także dodać zależność javax tak jak ci wyżej napisali, ale to twoje IDE samo powinno zaproponować. Na koniec w jakiejś swojej mainowej klasie którą odpalasz zwyczajnie stwórz obiekt User repository i tyle. Żadnego ręcznego tworzenia obiektów przez AppContext i żadnych @Bean. Jak Ci się uda, to wróć po dalsze instrukcje jak poradzić sobie z konstruktorem.
BTW: Polecam książkę "Spring w akcji" na początek będzie akurat.

0

Nie mam w projekcie pom-a, a o ile się nie mylę dependency wrzucamy właśnie tam.

OK, podsumowując mógłby ktoś jeszcze rzucić okiem na to i powiedzieć czy to podejście jest akceptowalne? Tu już odszedłem kompletnie od pliku xml
User:
http://pastebin.com/a764nANe

UserRepository
http://pastebin.com/0pcbhwh1

Main:

      ApplicationContext ctx = 
   		   new AnnotationConfigApplicationContext(UserRepository.class);
      
      UserRepository obj = (UserRepository)ctx.getBean("userRepository");
      
      User user1 = new User(1, "login", "pass", "privileges", 0);
      obj.setUser1(user1);
      obj.printUser1();
      
      obj.printUser2();

Konsola:
user1 : User [id=1, login=login, password=pass, username=privileges, privileges=0]
user2 : null

Chodzi mi głównie o to, czy teraz userów mam sobie wpisywać w ten sposób " z palca" w Mainie, że robię ich obiekty i później obj.setUser..?

0

Nie musisz tych userów tak robić, ale jeśli chcesz ich mieć kilku to niestety ale musisz gdzieś te obiekty zdeklarować. Jak nie chcesz w xmlu to musisz zrobić klasę z adnotacją @Configuration i z tymi @Bean w klasie.

0

Ogólnie to wycinek takiego projektu robionego w ramach nauki J2EE - to taki panel logowania/rejestracji/administratora z bazą danych Userów w sqllite, dlatego ten konstruktor w User musi zostać. Na koniec sobie wymyśliłem wścibienie tam gdzieś Springa i stąd ten temat i problem

DTO - pod jakim szyldem można poszukać pojęcia tego itp. żeby coś więcej o tym się dowiedzieć? Oczywiście nie chodzi mi o krótką definicję, tylko o wskazanie tematyki - czy mam szukać literatury o wzorcach projektowych, czy np. o projektowaniu aplikacji ee?

1 użytkowników online, w tym zalogowanych: 0, gości: 1