2017-02-22 130 views
0

我在我的Spring引導休息服務Application中遇到下面的異常。有時,當我啓動服務時會發生此異常。我能夠在4或5次嘗試後啓動該服務。任何解決方案讚賞。Spring Boot Rest服務Bean創建異常

RuntimeException generated in Method : org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBeanand exception messageError creating bean with name 'changeRecordService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.att.vtm.changerecord.services.changerecord.wrapper.IChangeRecordAdapter com.att.vtm.changerecord.services.changerecord.ChangeRecordService.iChangeRecordAdapter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'injectChangeRecordDaoAdapter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.att.vtm.changerecord.dao.VTMRefUserUpdateHistoryRepository com.att.vtm.changerecord.services.changerecord.wrapper.ChangeRecordDaoAdapter.vTMRefUserUpdateHistoryRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.att.vtm.changerecord.dao.VTMRefUserUpdateHistoryRepository] 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)} 

這是我的春天啓動主類

@SpringBootApplication(exclude = { HypermediaAutoConfiguration.class }) 
@EnableSwagger2 
@EnableCaching 
public class Application { 

    private static String adapterType; 

    public static String getAdapterType() { 
     return adapterType; 
    } 

    public static void setAdapterType(String adapterType) { 
     Application.adapterType = adapterType; 
    } 

    public static void main(String[] args) { 

     if (args.length != 0) { 
      Application.setAdapterType(args[0]); 

     } else { 
      Application.setAdapterType("DAO"); 
     } 

     try { 

      SpringApplication.run(Application.class, args); 

     } catch (Exception runtimeException) { 
      System.out.println(
        "RuntimeException generated in Method : " + runtimeException.getStackTrace()[1].getClassName() + "#" 
          + runtimeException.getStackTrace()[1].getMethodName() + "and exception message" 
          + runtimeException.getMessage()); 
      // Runtime.getRuntime().addShutdownHook(hook); 
     } 
    } 

    /** 
    * Tweak the connection pool used by Jetty to handle incoming HTTP 
    * minThreads & maxThreads connections 
    * 
    * @param port 
    * @param maxThreads 
    * @param minThreads 
    * @param idleTimeout 
    * @return 
    */ 
    @Bean 
    public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory(
      @Value("${server.port}") final String port, 
      @Value("${jetty.threadPool.maxThreads:200}") final String maxThreads, 
      @Value("${jetty.threadPool.minThreads:50}") final String minThreads, 
      @Value("${jetty.threadPool.idleTimeout:60000}") final String idleTimeout) { 

     final JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(
       Integer.valueOf(port)); 
     factory.addServerCustomizers(new JettyServerCustomizer() { 
      public void customize(Server server) { 
       final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class); 
       threadPool.setMaxThreads(Integer.valueOf(maxThreads)); 
       threadPool.setMinThreads(Integer.valueOf(minThreads)); 
       threadPool.setIdleTimeout(Integer.valueOf(idleTimeout)); 
      } 

     }); 
     return factory; 
    } 

    @Bean 
    public Docket newsApi() { 
     return new Docket(DocumentationType.SWAGGER_2).groupName("changerecord").apiInfo(apiInfo()).select() 
       .paths(regex("/bsi/.*")).build().directModelSubstitute(XMLGregorianCalendar.class, MixIn.class); 
    } 

    public static interface MixIn { 
     @JsonIgnore 
     public void setYear(int year); 
    } 

    /** 
    * 
    * @return 
    */ 
    private ApiInfo apiInfo() { 
     return new ApiInfoBuilder().title("Catalog Service REST APIs").description("Microservice REST APIs") 
       .termsOfServiceUrl("http://....").contact("TechMahindra").license("TechMahindra Licensed") 
       .licenseUrl("https://techmahindra.com").version("2.0").build(); 
    } 
} 

這是我的控制器類。

@RestController 
@RequestMapping("/bsi/vtm/changerecord") 
public class ChangeRecordController { 

    @Autowired 
    private ChangeRecordService changerecordService; 

    private static final Logger LOG = LoggerFactory.getLogger(ChangeRecordController.class); 

這是我的服務類。

@org.springframework.stereotype.Service 
public class ChangeRecordService { 
      private static final Logger LOG = LoggerFactory.getLogger(ChangeRecordService.class); 

@Autowired 
private IChangeRecordAdapter iChangeRecordAdapter; 

這是變更記錄默認地將Impl

public class ChangeRecordDaoAdapter extends IChangeRecordAdapter { 

    private static final Logger LOG = LoggerFactory.getLogger(ChangeRecordDaoAdapter.class); 

    @Autowired 
    private VTMRefUserUpdateHistoryRepository vTMRefUserUpdateHistoryRepository; 

    @Autowired 
    private NotificationHelper notificationHelper; 

    @Autowired 
    private SearchRepository searchRepository; 

    @Autowired 
    private CounterRepository counterRepository; 

    @Autowired 
    private ProducerConfiguration producerConfiguration; 


    @Autowired 
    private ChangeRecordRepository changerecordRepository; 

這是我的通知幫手

package com.att.vtm.changerecord.services.changerecord.wrapper; 

    public class NotificationHelper { 

    private static final Logger LOG = LoggerFactory.getLogger(NotificationHelper.class); 
    @Autowired 
    private ChangeRecordRepository changeRecordRepository; 

    @Autowired 
    private ImpactedGroupsSearchCriteria impactedGroupsSearchCriteria; 

    @Autowired 
    private TechnologiesSearchCriteria technologiesSearchCriteria; 

    @Autowired 
    private SearchGroupRepository searchGroupRepository; 

    @Autowired 
    private CbusEmailClient client; 

    @Autowired 
    private NotificationTrackingRepository notificationTrackingRepository; 

    @Autowired 
    private VTMRefUserUpdateHistoryRepository userUpdateHistoryRepository; 


    @Value("${vtm.url.service.userMgmt.getProfile}") 
    private String userMgmtServiceURL; 

這是我InjectConfiguration

package com.att.vtm.changerecord.conditionalinjection; 

import javax.sql.DataSource; 

import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Conditional; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.jdbc.datasource.DriverManagerDataSource; 

import com.att.vtm.changerecord.services.approverreviewer.wrapper.ApproverReviewerDaoAdapter; 
import com.att.vtm.changerecord.services.changerecord.wrapper.ChangeRecordDaoAdapter; 
import com.att.vtm.changerecord.services.changerecord.wrapper.ChangeRecordMetadataDaoAdapter; 
import com.att.vtm.changerecord.services.changerecord.wrapper.ChangeRecordReportAdapter; 
import com.att.vtm.changerecord.services.changerecord.wrapper.ChangeRecordTaskDaoAdapter; 
import com.att.vtm.changerecord.services.changerecord.wrapper.NotificationHelper; 
import com.att.vtm.crjob.services.crjob.wrapper.CRJobDaoAdapter; 
import com.att.vtm.crjob.services.crjob.wrapper.DeviceTestJobsDaoAdapter; 


@Configuration 
public class InjectionConfiguration { 

    @Value("${db.driver}") 
    private String DB_DRIVER; 

    @Value("${db.password}") 
    private String DB_PASSWORD; 

    @Value("${db.url}") 
    private String DB_URL; 

    @Value("${db.username}") 
    private String DB_USERNAME; 


    @Bean 
    @Conditional(DaoCondition.class) 
    public ChangeRecordDaoAdapter injectChangeRecordDaoAdapter() throws Exception{ 
     System.out.println("***INJECTING ChangeRecordDaoAdapter...****"); 
     return new ChangeRecordDaoAdapter(); 
    } 

    @Bean 
    @Conditional(DaoCondition.class) 
    public ChangeRecordMetadataDaoAdapter injectChangeRecordMetadataDaoAdapter() throws Exception{ 
     System.out.println("***INJECTING ChangeRecordMetadataDaoAdapter...****"); 
     return new ChangeRecordMetadataDaoAdapter(); 
    } 

    @Bean 
    @Conditional(DaoCondition.class) 
    public NotificationHelper injectNotificationHelper() throws Exception{ 
     System.out.println("***INJECTING NotificationHelper...****"); 
     return new NotificationHelper(); 
    } 

    @Bean 
    @Conditional(DaoCondition.class) 
    public ChangeRecordTaskDaoAdapter injectChangeRecordTaskDaoAdapter() throws Exception{ 
     System.out.println("***INJECTING ChangeRecordTaskDaoAdapter...****"); 
     return new ChangeRecordTaskDaoAdapter(); 
    } 

    @Bean 
    @Conditional(DaoCondition.class) 
    public CRJobDaoAdapter injectCRJobDaoAdapter() throws Exception{ 
     System.out.println("***INJECTING CRJob DAO ADAPTER...****"); 
     return new CRJobDaoAdapter(); 
    } 


    @Bean 
    @Conditional(DaoCondition.class) 
    public DeviceTestJobsDaoAdapter injectDeviceTestJobsDaoAdapter() throws Exception{ 
     System.out.println("***INJECTING DeviceTestJobs DAO ADAPTER...****"); 
     return new DeviceTestJobsDaoAdapter(); 
    } 

    @Bean 
    @Conditional(DaoCondition.class) 
    public ChangeRecordReportAdapter injectChangeRecordReportAdapter() throws Exception{ 
     System.out.println("***....INJECTING DeviceTestJobs DAO ADAPTER.......****"); 
     return new ChangeRecordReportAdapter(); 
    } 

    @Bean 
    @Conditional(DaoCondition.class) 
    public ApproverReviewerDaoAdapter injectApproverReviewerDaoAdapter() throws Exception{ 
     System.out.println("***....INJECTING ApproverReviewerDaoAdapter.......****"); 
     return new ApproverReviewerDaoAdapter(); 
    } 

    @Bean 
    public JdbcTemplate jdbcTemplate() 
    { 
     System.out.println("***INJECTING get jdbcTemplate ...****"); 
     return new JdbcTemplate(dataSource()); 
    } 

    @Bean 
    public DataSource dataSource() { 
    DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
    System.out.println("***INJECTING dataSource DAO ADAPTER...****"); 
    System.out.println(" DriverName :"+DB_DRIVER); 
    System.out.println(" DB_URL :"+DB_URL); 
    System.out.println(" DB_USERNAME :"+DB_USERNAME); 
    System.out.println(" DB_PASSWORD :"+DB_PASSWORD); 

    dataSource.setDriverClassName(DB_DRIVER); 
    dataSource.setUrl(DB_URL); 
    dataSource.setUsername(DB_USERNAME); 
    dataSource.setPassword(DB_PASSWORD); 
    return dataSource; 
    } 

} 

這是我的VTMRefUpdateRepository

package com.att.vtm.changerecord.dao; 

import java.util.List; 

import org.springframework.data.mongodb.repository.MongoRepository; 
import org.springframework.data.mongodb.repository.Query; 

import com.att.vtm.changerecord.dto.VTMRefUserUpdateHistory; 

public interface VTMRefUserUpdateHistoryRepository extends MongoRepository<VTMRefUserUpdateHistory, String> { 
    // @Query("select * from VTMRefUserUpdateHistory a where v.ticketNo = ?1") 
    @Query("{ 'ticketNo' : ?0 }") 
    public List<VTMRefUserUpdateHistory> findByTicketNo(String ticketNo); 

    // @Query("select * from VTMRefUserUpdateHistory a where v.pRNumber = ?1") 
    @Query("{ 'pRNumber' : ?0 }") 
    public List<VTMRefUserUpdateHistory> findByPRNumber(String pRNumber); 

    // @Query("select * from VTMRefUserUpdateHistory a where v.cRNumber = ?1") 
    @Query("{ 'cRNumber' : ?0 }") 
    public List<VTMRefUserUpdateHistory> findByCRNumber(String cRNumber); 


    public List<VTMRefUserUpdateHistory> findByCRNumberAndFieldNameAndNewValue(String cRNumber, String fieldName, String newValue); 
} 
+0

爲什麼錯綜複雜的設置?你的應用程序監聽器實際上是危險的,當spring啓動關閉時,close方法已經被調用。所以請刪除它。 'ThrowExceptionIfHandlerNotFound'可以通過'application.properties'設置,所以不需要破解。然後,這消除了與上下文一起破解的需要,這可能也會解決您的問題。 –

+0

您的VTMRefUserUpdateHistoryRepository是用@Repository還是@Component註解的? – alfcope

+0

我不喜歡'@ CoponentScan'註釋的值。我認爲星號正在混亂。試試這個:'@ComponentScan(「com.att.vtm」)' –

回答

0

您需要添加@Service註解爲您服務。 嘗試以下,

@Service 
public class ChangeRecordService { 
    // your code 
} 

檢查您IChangeRecordAdapter類

+0

謝謝麻雀。服務註釋已經存在了。我剛剛編輯了我的帖子。其他建議值得讚賞。 – user3911339

0

你的代碼是有缺陷的,至少ApplicationListener不需要接合,該DispatcherServlet屬性可以簡單地通過在指定它來設置application.properties

首先將spring.mvc.throw-exception-if-no-handler-found=true添加到您的application.properties,並刪除DispatcherServlet的獲取和修改。

這會減少您現在的Application類到簡單的應用程序啓動。

@SpringBootApplication 
@EnableSwagger2 
@ComponentScan("com.att.vtm.*") 
@EnableAutoConfiguration(exclude = {HypermediaAutoConfiguration.class}) 
@EnableCaching 
@EnableMongoRepositories(value = { "com.att.vtm" }) 


public class Application { 

    private static String adapterType; 

    public static String getAdapterType(){ 
     return adapterType; 
    } 

    public static void setAdapterType(String adapterType){ 
     Application.adapterType = adapterType; 
    } 

    public static void main(String[] args) { 

     if(args.length != 0){ 
      Application.setAdapterType(args[0]); 

     }else{ 
      Application.setAdapterType("DAO"); 
     } 

     try{ 

      SpringApplication.run(Application.class, args); 

     } 
     catch(Exception runtimeException){ 
      System.out.println("RuntimeException generated in Method : "+ runtimeException.getStackTrace()[1].getClassName() 
        +"#"+runtimeException.getStackTrace()[1].getMethodName() 
        +"and exception message"+runtimeException.getMessage()); 
      //Runtime.getRuntime().addShutdownHook(hook); 
     }  
    } 

    /** 
    * Tweak the connection pool used by Jetty to handle incoming HTTP minThreads & maxThreads connections 
    * @param port 
    * @param maxThreads 
    * @param minThreads 
    * @param idleTimeout 
    * @return 
    */ 
    @Bean 
    public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory(@Value("${server.port}") final String port, 
       @Value("${jetty.threadPool.maxThreads:200}") final String maxThreads, 
       @Value("${jetty.threadPool.minThreads:50}") final String minThreads, 
       @Value("${jetty.threadPool.idleTimeout:60000}") final String idleTimeout) { 

       final JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(Integer.valueOf(port)); 
       factory.addServerCustomizers(new JettyServerCustomizer() { 
       public void customize(Server server) { 
       final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class); 
       threadPool.setMaxThreads(Integer.valueOf(maxThreads)); 
       threadPool.setMinThreads(Integer.valueOf(minThreads)); 
       threadPool.setIdleTimeout(Integer.valueOf(idleTimeout)); 
      } 

     }); 
    return factory; 
    } 

    @Bean 
    public Docket newsApi() { 
     return new Docket(DocumentationType.SWAGGER_2) 
       .groupName("changerecord") 
       .apiInfo(apiInfo()) 
       .select()    
       .paths(regex("/bsi/.*")) 
       .build() 
       .directModelSubstitute(XMLGregorianCalendar.class, MixIn.class); 
    } 

    public static interface MixIn { 
     @JsonIgnore 
     public void setYear(int year); 
    } 

    /** 
    * 
    * @return 
    */ 
    private ApiInfo apiInfo() { 
     return new ApiInfoBuilder() 
       .title("Catalog Service REST APIs") 
       .description("Microservice REST APIs") 
       .termsOfServiceUrl("http://....") 
       .contact("TechMahindra") 
       .license("TechMahindra Licensed") 
       .licenseUrl("https://techmahindra.com") 
       .version("2.0") 
       .build(); 
    } 
} 

我也建議不加JettyEmbeddedServletContainerFactory但只有定製的豆,春天開機檢測的,他們將被應用。只需將您的JettyEmbeddedServletContainerFactory替換爲JettyServerCustomizer即可。

@Bean 
public JettyServerCustomizer threadPoolCustomizer(Value("${jetty.threadPool.maxThreads:200}") final Integer maxThreads, 
      @Value("${jetty.threadPool.minThreads:50}") final Integer minThreads, 
      @Value("${jetty.threadPool.idleTimeout:60000}") final Integer idleTimeout) { 
    return new JettyServerCustomizer() { 
     public void customize(Server server) { 
      final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class); 
      threadPool.setMaxThreads(maxThreads); 
      threadPool.setMinThreads(minThreads); 
      threadPool.setIdleTimeout(idleTimeout); 
     } 
} 

這樣可以降低Application類的複雜度。

但我確實認爲,這裏的主要問題是您的聽衆和使用靜態參考的東西。如上所述,你不需要它們。

其他一些要考慮的事情,我建議你把Application類放在com.att.vtm包中(如果它還沒有的話)。有了這個,你也可以在課堂上清理你的註釋。

@SpringBootApplication(exclude = {HypermediaAutoConfiguration.class}) 
@EnableSwagger2 
@EnableCaching 
public class Application { ... } 

很多註釋已經由@SpringBootApplication inmplied我建議利用,爲你的優勢。

更新1

你的JDBC配置可以/也應該在application.properties重命名db.*屬性spring.datasource屬性和從InjectionConfiguration刪除JdbcTemplateDataSource創作,讓春天開機搞定。然後在該類上添加@Conditional而不是在單獨的@Bean方法中。

spring.datasource.driver-class-name=${db.driver} 
spring.datasource.url=${db.url} 
spring.datasource.username=${db.username} 
spring.datasource.password=${db.password} 

注:可以或許離開了spring.datasource.driver-class-name作爲從spring.datasource.url財產推斷。

+0

我已經按建議進行了修改,仍然得到了例外。請您提出其他解決方案 – user3911339

+0

增加了一些額外的刪除問題,你可以在你的問題中加入你的DaoCondition。 –

+0

大家好,你可以請通過Class NotificationHelper和ChangeRecordDaoAdapter類。我有自動裝配VTMRefUserUpdateHistoryRepository在這兩個類以及我有自動裝配NotifyHelper在ChangeRecordDaoAdapter。這是一個問題?是否存在循環類自動生成問題。請幫助解決問題。 – user3911339