enable feign client and feign config indexing and reconciling to keep track of dependencies and trigger re-reconciling
This commit is contained in:
@@ -38,6 +38,7 @@ import org.springframework.ide.vscode.boot.java.reconcilers.BeanPostProcessingIg
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.BeanRegistrarDeclarationReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.Boot3NotSupportedTypeReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.EntityIdForRepoReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.FeignClientReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.HttpSecurityLambdaDslReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.ImplicitWebAnnotationNamesReconciler;
|
||||
import org.springframework.ide.vscode.boot.java.reconcilers.ModulithTypeReferenceViolationReconciler;
|
||||
@@ -74,6 +75,10 @@ public class JdtConfig {
|
||||
return new BeanRegistrarDeclarationReconciler(server.getQuickfixRegistry(), springIndex);
|
||||
}
|
||||
|
||||
@Bean FeignClientReconciler feignClientReconciler(SpringMetamodelIndex springIndex) {
|
||||
return new FeignClientReconciler(springIndex);
|
||||
}
|
||||
|
||||
@Bean AutowiredFieldIntoConstructorParameterReconciler autowiredFieldIntoConstructorParameterReconciler(SimpleLanguageServer server) {
|
||||
return new AutowiredFieldIntoConstructorParameterReconciler(server.getQuickfixRegistry());
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.java.beans;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -31,10 +32,13 @@ import org.eclipse.lsp4j.jsonrpc.messages.Tuple;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Tuple.Two;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.boot.java.utils.ASTUtils;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CachedSymbol;
|
||||
import org.springframework.ide.vscode.boot.java.utils.SpringIndexerJavaContext;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationAttributeValue;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.AnnotationMetadata;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.InjectionPoint;
|
||||
@@ -53,8 +57,11 @@ public class FeignClientSymbolProvider implements SymbolProvider {
|
||||
|
||||
WorkspaceSymbol symbol = result.getFirst();
|
||||
Bean beanDefinition = result.getSecond();
|
||||
|
||||
context.getGeneratedSymbols().add(new CachedSymbol(context.getDocURI(), context.getLastModified(), symbol));
|
||||
context.getBeans().add(new CachedBean(context.getDocURI(), beanDefinition));
|
||||
|
||||
markNewFeignConfigTypeForReconciling(beanDefinition, context);
|
||||
}
|
||||
}
|
||||
catch (BadLocationException e) {
|
||||
@@ -62,6 +69,19 @@ public class FeignClientSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void markNewFeignConfigTypeForReconciling(Bean beanDefinition, SpringIndexerJavaContext context) {
|
||||
List<String> configurationTypes = Arrays.stream(beanDefinition.getAnnotations())
|
||||
.filter(annotation -> annotation.getAnnotationType().equals(Annotations.FEIGN_CLIENT))
|
||||
.map(annotation -> annotation.getAttributes())
|
||||
.filter(attributes -> attributes.containsKey("configuration"))
|
||||
.map(attributes -> attributes.get("configuration"))
|
||||
.flatMap(attributeValues -> Arrays.stream(attributeValues))
|
||||
.map(attributeValue -> attributeValue.getName())
|
||||
.toList();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Two<WorkspaceSymbol, Bean> createSymbol(Annotation node, ITypeBinding annotationType, Collection<ITypeBinding> metaAnnotations, TextDocument doc) throws BadLocationException {
|
||||
String annotationTypeName = annotationType.getName();
|
||||
Collection<String> metaAnnotationNames = metaAnnotations.stream()
|
||||
@@ -94,7 +114,7 @@ public class FeignClientSymbolProvider implements SymbolProvider {
|
||||
.toArray(AnnotationMetadata[]::new);
|
||||
|
||||
Bean beanDefinition = new Bean(beanName, beanType == null ? "" : beanType.getQualifiedName(), location, injectionPoints, supertypes, annotations, false, symbol.getName());
|
||||
|
||||
|
||||
return Tuple.two(symbol, beanDefinition);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
|
||||
@Override
|
||||
public boolean visit(TypeDeclaration classDecl) {
|
||||
if (isApplicableClass(project, cu, classDecl)) {
|
||||
if (isApplicableClass(project, cu, classDecl, context)) {
|
||||
SimpleName nameAst = classDecl.getName();
|
||||
ReconcileProblemImpl problem = new ReconcileProblemImpl(getProblemType(), PROBLEM_LABEL,
|
||||
nameAst.getStartPosition(), nameAst.getLength());
|
||||
@@ -92,7 +92,7 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isApplicableClass(IJavaProject project, CompilationUnit cu, TypeDeclaration classDecl) {
|
||||
private boolean isApplicableClass(IJavaProject project, CompilationUnit cu, TypeDeclaration classDecl, ReconcilingContext context) {
|
||||
if (classDecl.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
@@ -128,15 +128,22 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
|
||||
// No '@Configuration' present. Check if any methods have '@Bean' annotation
|
||||
for (MethodDeclaration m : classDecl.getMethods()) {
|
||||
if (isBeanMethod(m) && !isException(project, classDecl)) {
|
||||
return true;
|
||||
if (isBeanMethod(m)) {
|
||||
if (context.isIndexComplete()) {
|
||||
if (!isException(project, classDecl, context)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new RequiredCompleteIndexException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isException(IJavaProject project, TypeDeclaration classDecl) {
|
||||
private boolean isException(IJavaProject project, TypeDeclaration classDecl, ReconcilingContext context) {
|
||||
if (springIndex == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -154,19 +161,30 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isConfiguredAsfeignConfigClass = Arrays.stream(beans)
|
||||
.flatMap(bean -> Arrays.stream(bean.getAnnotations()))
|
||||
.filter(annotation -> annotation.getAnnotationType().equals(Annotations.FEIGN_CLIENT))
|
||||
.map(annotation -> annotation.getAttributes().get("configuration"))
|
||||
.flatMap(attributeValues -> attributeValues != null ? Arrays.stream(attributeValues) : Stream.empty())
|
||||
.anyMatch(attributeValue -> attributeValue.getName().equals(beanClassName));
|
||||
List<Bean> feignClients = Arrays.stream(beans)
|
||||
.filter(bean -> isConfiguredAsFeignConfigClass(bean, beanClassName))
|
||||
.toList();
|
||||
|
||||
if (isConfiguredAsfeignConfigClass) {
|
||||
if (!feignClients.isEmpty()) {
|
||||
|
||||
// record dependency for feign clients that have this type configured as feign configuration
|
||||
for (Bean feignClient : feignClients) {
|
||||
context.addDependency(feignClient.getType());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isConfiguredAsFeignConfigClass(Bean bean, String beanClassName) {
|
||||
return Arrays.stream(bean.getAnnotations())
|
||||
.filter(annotation -> annotation.getAnnotationType().equals(Annotations.FEIGN_CLIENT))
|
||||
.map(annotation -> annotation.getAttributes().get("configuration"))
|
||||
.flatMap(attributeValues -> attributeValues != null ? Arrays.stream(attributeValues) : Stream.empty())
|
||||
.anyMatch(attributeValue -> attributeValue.getName().equals(beanClassName));
|
||||
}
|
||||
|
||||
private static boolean isBeanMethod(MethodDeclaration m) {
|
||||
AnnotationHierarchies annotationHierarchies = AnnotationHierarchies.get(m);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2025 Broadcom, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.annotations.AnnotationHierarchies;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.SpringProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.Bean;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.BeanMethodContainerElement;
|
||||
import org.springframework.ide.vscode.commons.protocol.spring.SpringIndexElement;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
|
||||
public class FeignClientReconciler implements JdtAstReconciler {
|
||||
|
||||
private final SpringMetamodelIndex springIndex;
|
||||
|
||||
public FeignClientReconciler(SpringMetamodelIndex springIndex) {
|
||||
this.springIndex = springIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IJavaProject project) {
|
||||
return SpringProjectUtil.hasDependencyStartingWith(project, "spring-cloud-openfeign-core", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProblemType getProblemType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTVisitor createVisitor(IJavaProject project, URI docURI, CompilationUnit cu, ReconcilingContext context) {
|
||||
return new ASTVisitor() {
|
||||
|
||||
@Override
|
||||
public boolean visit(TypeDeclaration node) {
|
||||
AnnotationHierarchies annotationHierarchy = AnnotationHierarchies.get(node);
|
||||
|
||||
if (!annotationHierarchy.isAnnotatedWith(node.resolveBinding(), Annotations.FEIGN_CLIENT)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<SpringIndexElement> elements = context.getCreatedIndexElements();
|
||||
|
||||
List<String> configurationTypes = elements.stream()
|
||||
.filter(element -> element instanceof Bean)
|
||||
.map(element -> (Bean) element)
|
||||
.flatMap(bean -> Arrays.stream(bean.getAnnotations()))
|
||||
.filter(annotation -> annotation.getAnnotationType().equals(Annotations.FEIGN_CLIENT))
|
||||
.map(annotation -> annotation.getAttributes())
|
||||
.filter(attributes -> attributes.containsKey("configuration"))
|
||||
.flatMap(attributes -> Arrays.stream(attributes.get("configuration")))
|
||||
.map(attribute -> attribute.getName())
|
||||
.toList();
|
||||
|
||||
List<BeanMethodContainerElement> beanMethodContainers = springIndex.getNodesOfType(BeanMethodContainerElement.class);
|
||||
|
||||
beanMethodContainers.stream().filter(beanContainer -> configurationTypes.contains(beanContainer.getType()))
|
||||
.map(beanContainer -> beanContainer.getLocation().getUri()).map(docURI -> UriUtil.toFileString(docURI))
|
||||
.forEach(file -> context.markForAffetcedFilesIndexing(file));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,8 +61,8 @@ public class ReconcilingContext {
|
||||
return isIndexComplete;
|
||||
}
|
||||
|
||||
public void addDependency(String typeOfConfigClassWithImport) {
|
||||
this.dependencies.add(typeOfConfigClassWithImport);
|
||||
public void addDependency(String type) {
|
||||
this.dependencies.add(type);
|
||||
}
|
||||
|
||||
public Set<String> getDependencies() {
|
||||
|
||||
@@ -41,6 +41,10 @@ public class SpringIndexerJavaDependencyTracker {
|
||||
public Multimap<String, String> getAllDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public Collection<String> get(String file) {
|
||||
return dependencies.get(file);
|
||||
}
|
||||
|
||||
public void update(String file, Set<String> dependenciesForFile) {
|
||||
dependencies.replaceValues(file, dependenciesForFile);
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2025 Broadcom
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Broadcom - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.reconcilers.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.eclipse.lsp4j.PublishDiagnosticsParams;
|
||||
import org.eclipse.lsp4j.TextDocumentIdentifier;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.ide.vscode.boot.app.SpringSymbolIndex;
|
||||
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
|
||||
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
|
||||
import org.springframework.ide.vscode.boot.java.Boot2JavaProblemType;
|
||||
import org.springframework.ide.vscode.boot.java.utils.test.TestFileScanListener;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.UriUtil;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@BootLanguageServerTest
|
||||
@Import(SymbolProviderTestConf.class)
|
||||
public class AddConfigurationIfBeansPresentAdvancedReconcilingTest {
|
||||
|
||||
@Autowired private BootLanguageServerHarness harness;
|
||||
@Autowired private JavaProjectFinder projectFinder;
|
||||
@Autowired private SpringSymbolIndex indexer;
|
||||
|
||||
private File directory;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
harness.intialize(null);
|
||||
|
||||
directory = new File(ProjectsHarness.class.getResource("/test-projects/test-feign-indexing/").toURI());
|
||||
|
||||
String projectDir = directory.toURI().toString();
|
||||
|
||||
// trigger project creation
|
||||
projectFinder.find(new TextDocumentIdentifier(projectDir)).get();
|
||||
|
||||
CompletableFuture<Void> initProject = indexer.waitOperation();
|
||||
initProject.get(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoErrorOnReferencedFeignConfigClass() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignConfigExample.java").toUri().toString();
|
||||
|
||||
PublishDiagnosticsParams diagnosticsResult = harness.getDiagnostics(docUri);
|
||||
List<Diagnostic> diagnostics = diagnosticsResult.getDiagnostics();
|
||||
|
||||
assertEquals(0, diagnostics.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorOnNotReferencedFeignConfigClass() throws Exception {
|
||||
String docUri = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignConfigNotRegistered.java").toUri().toString();
|
||||
|
||||
PublishDiagnosticsParams diagnosticsResult = harness.getDiagnostics(docUri);
|
||||
List<Diagnostic> diagnostics = diagnosticsResult.getDiagnostics();
|
||||
|
||||
assertEquals(1, diagnostics.size());
|
||||
assertEquals(Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION.getCode(), diagnostics.get(0).getCode().getLeft());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorGoesAwayWhenFeignClientMentionsFeignConfig() throws Exception {
|
||||
String feignClientDocUri = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignClientExample.java").toUri().toString();
|
||||
String feignConfigRegisterd = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignConfigExample.java").toUri().toString();
|
||||
String feignConfigNotRegisterd = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignConfigNotRegistered.java").toUri().toString();
|
||||
|
||||
// now change the config class source code and update doc
|
||||
TestFileScanListener fileScanListener = new TestFileScanListener();
|
||||
indexer.getJavaIndexer().setFileScanListener(fileScanListener);
|
||||
|
||||
String feignClientSource = FileUtils.readFileToString(UriUtil.toFile(feignClientDocUri), Charset.defaultCharset());
|
||||
String updatedFeignClientSource = feignClientSource.replace("@FeignClient(name = \"stores\", configuration = FeignConfigExample.class)",
|
||||
"@FeignClient(name = \"stores\", configuration = {FeignConfigNotRegistered.class, FeignConfigExample.class})");
|
||||
|
||||
CompletableFuture<Void> updateFuture = indexer.updateDocument(feignClientDocUri, updatedFeignClientSource, "test triggered");
|
||||
updateFuture.get(5, TimeUnit.SECONDS);
|
||||
|
||||
// check if the bean registrar files have been re-scanned
|
||||
fileScanListener.assertScannedUri(feignClientDocUri, 1);
|
||||
fileScanListener.assertScannedUri(feignConfigNotRegisterd, 1);
|
||||
fileScanListener.assertScannedUri(feignConfigRegisterd, 1);
|
||||
fileScanListener.assertFileScanCount(3);
|
||||
|
||||
// check diagnostics result
|
||||
PublishDiagnosticsParams diagnosticsResult = harness.getDiagnostics(feignConfigNotRegisterd);
|
||||
List<Diagnostic> diagnostics = diagnosticsResult.getDiagnostics();
|
||||
assertEquals(0, diagnostics.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testErrorAppearsWhenFeignClientNotMentionsFeignConfigAnymore() throws Exception {
|
||||
String feignClientDocUri = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignClientExample.java").toUri().toString();
|
||||
String feignConfigRegisterd = directory.toPath().resolve("src/main/java/com/example/feign/demo/FeignConfigExample.java").toUri().toString();
|
||||
|
||||
// now change the config class source code and update doc
|
||||
TestFileScanListener fileScanListener = new TestFileScanListener();
|
||||
indexer.getJavaIndexer().setFileScanListener(fileScanListener);
|
||||
|
||||
String feignClientSource = FileUtils.readFileToString(UriUtil.toFile(feignClientDocUri), Charset.defaultCharset());
|
||||
String updatedFeignClientSource = feignClientSource.replace("@FeignClient(name = \"stores\", configuration = FeignConfigExample.class)",
|
||||
"@FeignClient(name = \"stores\")");
|
||||
|
||||
CompletableFuture<Void> updateFuture = indexer.updateDocument(feignClientDocUri, updatedFeignClientSource, "test triggered");
|
||||
updateFuture.get(5, TimeUnit.SECONDS);
|
||||
|
||||
// check if the bean registrar files have been re-scanned
|
||||
fileScanListener.assertScannedUri(feignClientDocUri, 1);
|
||||
fileScanListener.assertScannedUri(feignConfigRegisterd, 1);
|
||||
fileScanListener.assertFileScanCount(2);
|
||||
|
||||
// check diagnostics result
|
||||
PublishDiagnosticsParams diagnosticsResult = harness.getDiagnostics(feignConfigRegisterd);
|
||||
List<Diagnostic> diagnostics = diagnosticsResult.getDiagnostics();
|
||||
assertEquals(1, diagnostics.size());
|
||||
assertEquals(Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION.getCode(), diagnostics.get(0).getCode().getLeft());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example.qualifier</groupId>
|
||||
<artifactId>feign-demo</artifactId>
|
||||
<artifactId>test-feign-indexing</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>feign-demo</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.springframework.context.annotation.Bean;
|
||||
public class FeignConfigExample {
|
||||
|
||||
@Bean
|
||||
public BeanType specialBean() {
|
||||
BeanType specialBean() {
|
||||
return new BeanType();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example.feign.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
public class FeignConfigNotRegistered {
|
||||
|
||||
@Bean
|
||||
BeanType specialBean2() {
|
||||
return new BeanType();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user