2015-04-22 17 views
7

Próbuję użyć adnotacji @Autowired dla klasy usług w aplikacji Spring Boot, ale nadal wyrzucam wyjątek No qualifying bean of type. Jeśli jednak zmienię klasę usługi na komponent bean, to działa poprawnie. To jest mój kod:Adnotacja przy uruchamianiu sprężyny @Autowirowany z usługi kończy się niepowodzeniem

package com.mypkg.domain; 
@Service 
public class GlobalPropertiesLoader { 

    @Autowired 
    private SampleService sampleService;   
} 

package com.mypkg.service; 
@Service 
public class SampleService{ 

} 

A to moja klasa SpringBoot:

package com.mypkg; 

import java.util.Set; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Import; 

@SpringBootApplication 
@EnableJpaRepositories 
@Import(RepositoryRestMvcConfiguration.class) 
@EnableTransactionManagement 
public class TrackingService { 
    private static final Logger LOGGER = LoggerFactory.getLogger(TrackingService.class); 

    static AnnotationConfigApplicationContext context; 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(TrackingService.class, args); 
     context = new AnnotationConfigApplicationContext(); 
     context.refresh(); 
     context.close(); 

    } 

} 

Kiedy próbuję uruchomić to pojawia się następujący wyjątek:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mypkg.service.SampleService] 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)} 

Ale kiedy usunąć Adnotacja @Service z klasy SampleService i dodaj ją jako komponent bean w mojej klasie AppConfig, jak poniżej, działa dobrze:

@Configuration 
public class AppServiceConfig { 

    public AppServiceConfig() { 
    } 

    @Bean(name="sampleService") 
    public SampleService sampleService(){ 
     return new SampleService(); 
    } 

} 

Klasy są w różnych pakietach. Nie używam @ComponentScan. Zamiast tego używam @SpringBootApplication, która robi to automatycznie. Jednak próbowałem również z ComponentScan, ale to nie pomogło.

Co ja tu robię źle?

+0

Czy możesz pokazać swoją klasę "Application" (ta z metodą "main")? –

+0

Mam zaktualizowane moje pytanie z kodem dla głównej klasy. – drunkenfist

+0

@drunkenfist Dlaczego zamykasz kontekst? Wiesz, że to zniszczy cały rytuał fasoli. – minion

Odpowiedz

15

Używasz dwóch sposobów budowania fasoli wiosennej. Musisz tylko użyć jednego z nich.

  1. @Service nad POJO

    @Service 
    public class SampleService 
    
  2. @Bean w klasie konfiguracji, które muszą być opatrzone @Configuration

    @Bean 
    public SampleService sampleService(){ 
        return new SampleService(); 
    } 
    

@Autowired został rozwiązany według typu klasy wtedy @Bean(name="sampleService") nie jest potrzebna, masz tylko jeden komponent bean o tym typie klasy.

Edycja 01

pakiet com.example

@SpringBootApplication 
public class Application implements CommandLineRunner { 

public static void main(String... args) { 
    SpringApplication.run(Application.class); 
} 

@Autowired 
private UserRepository userRepository; 

@Autowired 
private UserService userService; 

@Override 
public void run(String... strings) throws Exception { 
    System.out.println("repo " + userRepository); 
    System.out.println("serv " + userService); 
} 
} 

pakiet com.example.config

@Configuration 
public class AppConfig { 

@Bean 
public UserRepository userRepository() { 
    System.out.println("repo from bean"); 
    return new UserRepository(); 
} 

@Bean 
public UserService userService() { 
    System.out.println("ser from bean"); 
    return new UserService(); 
} 
} 

pakiet com.example.repository

@Service 
public class UserRepository { 

@PostConstruct 
public void init() { 
    System.out.println("repo from @service"); 
} 
} 

pakiet com.example.service

@Service 
public class UserService { 

@PostConstruct 
public void init() { 
    System.out.println("service from @service"); 
} 

} 

Za pomocą tego kodu możesz skomentować klasę AppConfig a następnie będziesz se jak UserRepository i UserService są autowired. Po tym komentarzu @Service w każdej klasie i uncomment AppConfig i klasy będą również autowyredowane.

+0

Myślę, że moje pytanie jest błędne. Używam tylko jednej z metod. Kiedy dodam adnotację do '@ Service' przez POJO, nie powiedzie się. Ale kiedy używam '@ Bean' w mojej klasie konfiguracji, to działa. Chcę wiedzieć, dlaczego sposób '@ Service' zawodzi. – drunkenfist

+0

Zaktualizowałem odpowiedź. static AnnotationConfigApplicationContext context; Jest używane? Spring Boot zarządza cyklem życia, więc nie wiesz, dlaczego używasz context.refresh() i context.close() –

+0

Dla mnie metoda '@ Service' nie działa. Jest pobierany tylko wtedy, gdy jest zadeklarowany jako '@ Bean'. – drunkenfist

Powiązane problemy