2017-02-22 157 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