Spring Boot Rest服务Bean创建异常

时间:2017-02-22 08:14:57

标签: spring spring-boot

我在Spring启动休息服务Application中遇到以下异常。当我启动服务时,有时会发生此异常。我可以在4或5次尝试后启动服务。感谢任何解决方案。

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

这是我的Spring Boot Main class

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

2 个答案:

答案 0 :(得分:0)

您需要为服务添加@Service注释。 尝试以下,

@Service
public class ChangeRecordService {
   // your code
}

还要检查你的IChangeRecordAdapter类

答案 1 :(得分:0)

您的代码存在缺陷,至少不需要ApplicationListenerDispatcherServlet上的属性可以通过在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但只添加自定义程序作为bean,Spring Boot会检测这些并且它们将被应用。只需将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隐含,我建议利用这些注释为您带来优势。

更新1

您的JDBC配置可能/应该application.propertiesdb.*属性重命名为spring.datasource属性,并从您的JdbcTemplateDataSource创建中删除{1}}让spring boot处理它。然后在类上添加InjectionConfiguration,而不是在单独的@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属性中推断出来的。