春季启动自动装配属性问题

huangapple go评论75阅读模式
英文:

Spring boot autowiring properties question

问题

我正在尝试使用Spring Boot的自动装配来深入了解它,但有一点我不太理解。在下面的代码中,启动类的自动装配是有效的,但在更高级别的类中却不是。结果是 "SpringApplication.run" 会正确打印出属性,但 "demo.print()" 则不会。有人能帮我理解为什么,以及如何使其正常工作吗?

package demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

@SpringBootApplication
@EnableConfigurationProperties(EmailProperties.class)
public class DemoApplication {

    @Autowired
    private EmailProperties properties;

    public static void main(String[] args) {

        SpringApplication.run(DemoApplication.class, args);

        DemoApplication demo = new DemoApplication();
        demo.print();

    }

    private void print() {
        System.out.println("Partner support: " + this.properties.getPartnerSupport());
    }

    DemoApplication(){
    }

    @Service
    static class Startup implements CommandLineRunner {

        @Autowired
        private EmailProperties properties;

        @Override
        public void run(String... strings) throws Exception {
            System.out.println("-----------------------------------------");
            System.out.println("Client support: " + this.properties.getClientSupport());
            System.out.println("Partner support: " + this.properties.getPartnerSupport());
            System.out.println("No reply to: " + this.properties.getNoReplyTo());
            System.out.println("Support reply to: " + this.properties.getSupportReplyTo());
            System.out.println("OpS notification: " + this.properties.getOpsNotification());
            System.out.println("-----------------------------------------");
        }
    }
}

如果需要,我可以发布演示代码的其他部分。谢谢。

英文:

I'm playing around with spring-boot auto wiring to learn more about it and I'm not understanding something. In the code below the autowiring for the startup class works, but the one in the highier level class does not. The result is the "SpringApplication.run" will print out the properties correctly, but "demo.print()" will not. Can someone help me understand why and how I would get it to work?

package demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
@SpringBootApplication
@EnableConfigurationProperties(EmailProperties.class)
public class DemoApplication {
@Autowired
private EmailProperties properties;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
DemoApplication demo = new DemoApplication();
demo.print();
}
private void print() {
System.out.println("Partner support: " + this.properties.getPartnerSupport());
}
DemoApplication(){
}
@Service
static class Startup implements CommandLineRunner {
@Autowired
private EmailProperties properties;
@Override
public void run(String... strings) throws Exception {
System.out.println("-----------------------------------------");
System.out.println("Client support: " + this.properties.getClientSupport());
System.out.println("Partner support: " + this.properties.getPartnerSupport());
System.out.println("No reply to: " + this.properties.getNoReplyTo());
System.out.println("Support reply to: " + this.properties.getSupportReplyTo());
System.out.println("OpS notification: " + this.properties.getOpsNotification());
System.out.println("-----------------------------------------");
}
}

}

I can post the other parts of the demo code if needed. Thanks.

答案1

得分: 2

当您调用 SpringApplication.run(DemoApplication.class, args); 时,Spring 将创建自己的 DemoApplication 实例,然后查看它是否具有 @Autowired 成员,并对它们进行自动装配。这通常被称为托管的bean

您的 @Service 类也将被自动实例化和自动装配,因为它还是一个 CommandLineRunner,所以在自动装配bean之后,Spring 将调用 run() 方法。

另一方面,当您调用 DemoApplication demo = new DemoApplication(); 时,您创建了自己的 DemoApplication 实例,该实例不会由 Spring 管理。因此,在 properties 字段中不会进行自动装配,该字段保持为 null

为了更好地理解 Spring 的工作原理,特别是托管实例与非托管实例的区别,我强烈建议您阅读 Spring Framework 参考文档的第一章,IoC 容器

英文:

When you invoke SpringApplication.run(DemoApplication.class, args);, Spring will create its own instance of DemoApplication, see that it has @Autowired members and autowire them. This is what's usually called a managed bean.

Your @Service class will also be instantiated and autowired automatically, and because it's also a CommandLineRunner, Spring will call the run() method after having autowired your beans.

On the other hand, when you invoke DemoApplication demo = new DemoApplication();, you create your own instance of DemoApplication, which is not managed by Spring. As a result, nothing will be autowired in the properties field, which stays null.

To better understand how Spring works, especially the managed vs non-managed instances part, I highly suggest you read the first chapter of the Spring Framework Reference, The IoC Container.

huangapple
  • 本文由 发表于 2020年9月16日 03:07:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63908362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定