2015-04-22 40 views
7

Tôi đang cố sử dụng chú thích @Autowired cho lớp Dịch vụ trong ứng dụng Khởi động mùa xuân, nhưng nó vẫn giữ ngoại lệ No qualifying bean of type. Tuy nhiên, nếu tôi thay đổi lớp dịch vụ thành một bean, thì nó hoạt động tốt. Đây là mã của tôi:Chú thích khởi động mùa xuân @Autowired of Service không hoạt động

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

    @Autowired 
    private SampleService sampleService;   
} 

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

} 

Và đây là lớp SpringBoot tôi:

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(); 

    } 

} 

Khi tôi cố gắng chạy này, tôi nhận được ngoại lệ sau đây:

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)} 

Nhưng khi tôi loại bỏ chú thích @Service từ lớp SampleService và thêm nó như là một bean trong lớp AppConfig của tôi như dưới đây, nó hoạt động tốt:

@Configuration 
public class AppServiceConfig { 

    public AppServiceConfig() { 
    } 

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

} 

Các lớp học có các gói khác nhau. Tôi không sử dụng @ComponentScan. Thay vào đó, tôi đang sử dụng @SpringBootApplication tự động thực hiện điều đó. Tuy nhiên, tôi đã thử với ComponentScan là tốt nhưng điều đó đã không giúp đỡ.

Tôi đang làm gì sai ở đây?

+0

Bạn có thể hiển thị lớp 'Application' của mình (lớp có phương thức' main') không? –

+0

Tôi đã cập nhật câu hỏi của mình với mã cho lớp chính. – drunkenfist

+0

@drunkenfist Tại sao bạn đóng ngữ cảnh? Bạn biết nó sẽ phá hủy tất cả các nghi thức đậu. – minion

Trả lời

15

Bạn đang sử dụng hai cách để tạo bean của Spring. Bạn chỉ cần sử dụng một trong số họ.

  1. @Service qua POJO

    @Service 
    public class SampleService 
    
  2. @Bean trong lớp cấu hình phải được chú thích với @Configuration

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

@Autowired được giải quyết theo loại lớp sau đó @Bean(name="sampleService") là không cần thiết là bạn chỉ có một bean với loại lớp đó.

EDIT 01

gói 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); 
} 
} 

gói 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(); 
} 
} 

gói com.example.repository

@Service 
public class UserRepository { 

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

gói com.example.service

@Service 
public class UserService { 

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

} 

Sử dụng mã này, bạn có thể bình luận lớp AppConfig và sau đó bạn sẽ se bao UserRepository và UserService được autowired. Sau đó bình luận @Service trong mỗi lớp và bỏ ghi chú AppConfig và các lớp sẽ được autowired quá.

+0

Tôi nghĩ rằng bạn đã nhận được câu hỏi của tôi sai. Tôi chỉ sử dụng một trong các phương pháp. Khi tôi chú thích nó với '@ Service' trên POJO, nó không thành công. Nhưng khi tôi sử dụng '@ Bean' trong lớp cấu hình của tôi, nó hoạt động. Tôi muốn biết tại sao cách '@ Service' lại thất bại. – drunkenfist

+0

Tôi đã cập nhật câu trả lời. ngữ cảnh tĩnh AnnotationConfigApplicationContext; Được sử dụng? khởi động mùa xuân quản lý vòng đời vì vậy không chắc chắn lý do tại sao bạn đang sử dụng context.refresh() và context.close() –

+0

Đối với tôi, phương thức '@ Service' không hoạt động. Nó chỉ tìm nạp nếu nó được khai báo là '@ Bean'. – drunkenfist

Các vấn đề liên quan