java - 更改 Autowired bean 类型会意外更改值吗?

标签 java spring spring-boot autowired

我尝试创建一个应用程序,但遇到了一些奇怪的行为。首先,我将完成我的设置。这是我的配置类:

ProblemApp.java

@SpringBootApplication
public class ProblemApp
{
    public static void main(String[] args)
    {
        var context = SpringApplication.run(ProblemApp.class);
        var tblController = context.getBean(TableController.class);
        tblController.printTable();
    }
    @Bean
    public TableController getTableController()
    {
        return new TableController();
    }
    @Bean("componentTable")
    public String[] getComponentTable() //weird
    {
        return new String[] { "application.components" };
    }
}

这是我的组件:

TableController.java

@Controller
public class TableController
{
    private static final Logger log = LoggerFactory.getLogger(TableController.class);

    @Autowired
    private String[] componentTable; //weird

    public void printTable()
    {
        log.info("Component table: " + Arrays.deepToString(componentTable));
    }
}

这是我的module-info.java和目录结构:

module problem.application
{
    exports application;
    exports controller;

    opens controller to spring.core;
    opens application to spring.core;

    requires spring.context;
    requires spring.boot;
    requires spring.boot.autoconfigure;
    requires spring.beans;
    requires spring.core;
    requires java.sql;
    requires org.slf4j;
}
src/main/java/
    application
        ProblemApp.java
    controller
        TableController.java
    module-info.java
src/test/java/ is empty
src/main/resources/ is empty

这是我用来检索依赖项的 pom.xml(在 Spring Tool Suite 4 中使用 Maven):

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>problem.application</groupId>
    <artifactId>problem-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Problematic application</name>
    <description>An application with some problems</description>

    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <release>12</release>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

</project>

这段代码按照我的预期工作。输出的相关部分是:

2019-09-11 10:55:21.351  INFO 21060 --- [           main] controller.TableController               : 
Component table: [application.components]

现在,我尝试将 Bean componentTable 的类型更改为 Object[]。在问题应用程序中:

@Bean("componentTable")
public Object[] getComponentTable() //weird
{
    return new Object[] { "application.components" };
}

在表 Controller 中:

@Autowired
private Object[] componentTable; //weird

突然,程序的输出发生了巨大的变化:

2019-09-11 10:57:05.630  INFO 10156 --- [           main] controller.TableController               : 
Component table: [org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor@b40bb6e, 
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@3f28bd56, 
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@3276732, 
org.springframework.context.annotation.ConfigurationClassPostProcessor@f74e835, 
org.springframework.context.support.PropertySourcesPlaceholderConfigurer@48c35007, 
org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar@4b3c354a, 
org.springframework.context.event.EventListenerMethodProcessor@31e3250d, 
org.springframework.context.event.DefaultEventListenerFactory@19fe4644, 
application.ProblemApp$$EnhancerBySpringCGLIB$$7e1f363f@21d8bcbe,
...
// more Spring-looking things and then environment information

这是怎么回事?

最佳答案

当自动写入 T 类型的数组或列表时,它会首先尝试将所有类型为 T 的 Bean 注入(inject)其中。所以对于:

@Autowired
private String[] componentTable; 

它会首先尝试注入(inject)所有类型为 String 的bean。然而,由于没有这样的 bean,它会尝试注入(inject)一个类型为 String[] 的 bean。当您将 componentTable bean 定义为 String[] 时,它将被注入(inject)。

遵循相同的逻辑:

@Autowired
private Object[] componentTable;

它会首先尝试注入(inject)所有类型为Object的bean。因为每个 bean 都必须是 Object 类型。这意味着所有的 spring beans 将被注入(inject)。因此它会打印出所有 Spring bean 信息。

关于java - 更改 Autowired bean 类型会意外更改值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57893233/

相关文章:

java - 如何使用 Java 和 SAX 解析我的简单 XML 文件?

java - 如何跟踪普通 Spring 微服务应用程序(非 Spring boot)中的请求?

java - 处理列表 "Optional operation"

java - 来自国家名称的 ISO2 国家代码

spring - Spring DispatcherServlet 与过滤器的关系

java - 如何在 Grails 或 Hibernate 中缩短它

gradle - spring boot jsps 没有被渲染

tomcat - 如何将我的 log4j.properties 文件提取到 .WAR 文件之外?

java - 如何在@RequestBody 中自定义将字符串转换为枚举?

java - FLAC或OGG在线媒体播放器