Случаи, когда может возникнуть ошибка - «Есть ли неразрешимая циклическая ссылка?» - PullRequest
1 голос
/ 23 октября 2019

Я получаю эту ошибку - есть неразрешимая циклическая ссылка? Возможно, в моем коде есть подозрение на автоматическое подключение:

@Configuration
public class Bean1 {

  @Autowired
  private Bean3 bean3;
  @Autowired
  private Bean2 bean2;
}
@Configuration
public class Bean2 {

  @Autowired
  private Bean3 bean3;
}

Может ли это вызвать циклическую зависимость и как?


Редактировать: Добавление исправления, которое работало для меня. Но в поисках причины, по которой это сработало ..

После того, как я сделал ленивую автопроводку Bean3 в Bean1, ошибка исчезла. Но я не могу понять, почему?

@Configuration
public class Bean1 {

  @Autowired
  @Lazy
  private Bean3 bean3;
  @Autowired
  private Bean2 bean2;
}

Добавление фактического кода bean-компонентов: Bean1-DbConfig Bean2-FindUser Bean3-DocumentClient

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.microsoft.azure.documentdb.Database;
import com.microsoft.azure.documentdb.DocumentClient;
import com.microsoft.azure.documentdb.DocumentCollection;
import com.microsoft.azure.spring.data.cosmosdb.config.AbstractDocumentDbConfiguration;
import com.microsoft.azure.spring.data.cosmosdb.config.DocumentDBConfig;
@Configuration
@PropertySource("classpath:application.properties")
public class DbConfig extends AbstractDocumentDbConfiguration {

  @Value("${db}")
  private String database;

  @Value("${key}")
  private String databaseURI;

  @Value("${someValue}")
  private String databaseKey;

  @Autowired
  private DocumentClient documentClient;

  @Override
  public DocumentDBConfig getConfig() {
    return DocumentDBConfig.builder(databaseURI, databaseKey, database).build();
  }

  public DocumentCollection getTodoCollection(String collectionName) {
    return documentClient
        .queryCollections("tst",
            "SELECT * FROM r WHERE r.id='" + collectionName + "'", null)
        .getQueryIterable().toList().get(0);
  }

  private Database getDb() {
    return null;
  }

}


import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.google.gson.Gson;
import com.microsoft.azure.documentdb.Document;
import com.microsoft.azure.documentdb.DocumentClient;
@Service
public class FindUser {


  @Autowired
  private UserRepository userRepository;
  @Lazy
  @Autowired
  private DocumentClient documentClient;

  @Autowired
  private DbConfig document;


  public String doSomething(String customerId) {
         return "something";
}}

pom. xml

<properties>
<azure.version>2.1.2</azure.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-documentdb-spring-boot-starter</artifactId>
            <version>2.0.4</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox-swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox-swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.fge</groupId>
            <artifactId>json-schema-core</artifactId>
            <version>1.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.everit.json</groupId>
            <artifactId>org.everit.json.schema</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Spring Boot Actuator for monitoring -->
        <!-- Google code formatter -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.threeten</groupId>
            <artifactId>threetenbp</artifactId>
            <version>0.7.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <scope>compile</scope>
        </dependency>

        <!-- Cucumber Dependency for java -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-java8</artifactId>
            <version>1.2.5</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>1.2.5</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-spring-boot-bom</artifactId>
                <version>${azure.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

Ответы [ 3 ]

1 голос
/ 23 октября 2019

Нет, там нет циклической зависимости .

Иерархия зависимостей:

Bean1 ──> Bean2 ──┐
  │               ↓
  └───────────> Bean3 

Даже если у вас была циклическая зависимость, она может вызвать толькоошибка, если вы используете инъекцию в конструктор , и, поскольку вы используете инъекцию в поле , по этой причине она никогда не завершится неудачей.

1 голос
/ 23 октября 2019

Нет, у вас нет круговой зависимости в случае, который вы определили. Как упомянуто @Andreas, это один из способов зависимости, а не циклический.

Циркуляр является зависимостью, как,

@Configuration
public class Bean2 {

  @Autowired
  private Bean3 bean3;

}

И

@Configuration
public class Bean3 {

  @Autowired
  private Bean2 bean2;
}

Этот видПример имеет тип циклической зависимости.

Есть способы избежать этого, например, использование @Autowire в методе установки объекта или использование @Lazy в объекте. Таким образом, один объект создается во время загрузки приложения, а другой - во время требования.

Надеюсь, что эта помощь.

0 голосов
/ 23 октября 2019

Это работает для меня. Убедитесь, что Bean3 в контексте, для экземпляров используйте аннотацию Component.

@Component
public class Bean3 {}
...