Java spring noob beans 和配置

Java spring noob beans and configuration

我正在尝试 运行 休闲 classes.

package com.example.demo;

import org.apache.catalina.core.ApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {

        var factory = new AnnotationConfigApplicationContext(AppConfig.class);
        test tst = factory.getBean(test.class);
        tst.getDummy().test();
        SpringApplication.run(DemoApplication.class, args);
    }

}

应用程序配置 class:

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    public test gettest(){
        return new test();
    }
//
    @Bean
    public test2 gettest2(){
        return new test2();
    }
}

第一次测试class:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
public class test{
    @Autowired
    test2 dummy;

    public void setDummy(test2 dummy) {
        this.dummy = dummy;
    }

    public test2 getDummy() {
        return dummy;
    }

    void test(){
        System.out.println("test");
    }
}

第二次测试class:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class test2{

    public test2(){

    }
    void test(){
        System.out.println("test2");
    }

}

我在 运行 时间收到这个错误

Field dummy in com.example.demo.test required a single bean, but 2 were found:
    - test2: defined in file [/Users/biliuta/IdeaProjects/demo/build/classes/java/main/com/example/demo/test2.class]
    - gettest2: defined by method 'gettest2' in class path resource [com/example/demo/AppConfig.class]

如果我从 AppConfig 注释掉 public test2 gettest2() bean,我会得到这个错误:

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gettest': Unsatisfied dependency expressed through field 'dummy'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.test2' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

为什么在第一种情况下找到了 test2 bean,而当我从 AppConfig 中将其注释掉时,它再也找不到了(在第一条错误消息中,您可以清楚地看到找到了 test2)? @Configure 注释是否必须将 bean 添加到上下文?

@Autowired 是如何工作的,它首先尝试按类型查找所需的 bean,而后备机制是按 bean 名称(例如:同一类型有多个 bean)

但是当您从 AppConfig 中禁用 @Bean 注释时,应该至少有一个类型为 Test2 的 bean,因为您已经使用 @Component 注释对 Test2 进行了注释,但是它找不到它。要解决此问题,您需要在 AppConfig class 上添加 @ComponentScan(basePackageClasses = { Test2.class }),如下所示

@Configuration
@ComponentScan(basePackageClasses = { Test2.class })
public class AppConfig {
@Bean
public Test gettest(){
    return new Test();
}

//@Bean
public Test2 gettest2(){
    return new Test2();
}
}

但是如果你启用bean注解如下

@Configuration
@ComponentScan(basePackageClasses = { Test2.class })
public class AppConfig {
@Bean
public Test gettest(){
    return new Test();
}

@Bean
public Test2 gettest2(){
    return new Test2();
}
}

您需要使用

更改测试中 Test2 的注入
 @Autowired
 Test2 test2;

或使用

 @Autowired
 Test2 gettest2;

当您定义 @Component 时,您定义了一个可以为自动装配找到的 bean

当您定义 @Bean(在`@Configuration 中)时,您定义了一个可用于自动装配的 bean

所以你定义了两次相同的 bean,导致 spring 无法知道哪个是正确的自动装配 bean

解决方法是只定义一次

有几种方法可以让您的 class 在 Spring / Spring Boot

中成为 bean
  • 使用 @Component 或任何其他 派生的 注释对您的 class 进行注释(@Service@Repository@Controller, @RestController)
  • 将您的 class 定义为 XML 配置中的 bean
  • 使用@Bean注释(这个只能应用于方法指定它returns一个由[=46=管理的bean ] 语境)。 @Bean 注解通常在配置中声明 classes 方法

当 Spring 初始化其上下文时,它会查找任何 bean 定义并创建 bean。在您的情况下,它会发现 testtest2 的重复声明,因此您需要删除配置 class 或从 class 中删除 @Component 注释]es.

有关详细信息,请参阅 Spring Bean documentation