Spring 自动装配调用了错误的构造函数

Spring Autowiring calling wrong constructor

我正在学习 Springs 注释和自动连接。我尝试了三种自动接线

  1. 构造函数
  2. Setter注入
  3. 方法

这是我的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- add entry for component scanning -->
    <context:component-scan base-package="com.aht.spring.entity"></context:component-scan>

</beans>

这些是我的实体

Coach.java

package com.aht.spring.entity.coach;

public interface Coach {

    String getDailyWorkOut();

    String getDailyFortune();
}

财富服务

package com.aht.spring.entity.fortune;

public interface FortuneService {

    String getFortune();
}

幸福财富服务

package com.aht.spring.entity.fortune;

import org.springframework.stereotype.Component;

@Component
public class HappyFortuneService implements FortuneService {

    public String getFortune() {
        return "Feel energetic for first half of trainning";
    }
}

足球教练

package com.aht.spring.entity.coach;

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

import com.aht.spring.entity.fortune.FortuneService;

@Component
public class FootBallCoach implements Coach {

    private FortuneService fortuneService;

    @Autowired
    public FootBallCoach(FortuneService fortuneService) {
        this.fortuneService = fortuneService;
    }

    public String getDailyWorkOut() {
        return "Practice one-on-one for 2 hours";
    }

    public String getDailyFortune() {
        return fortuneService.getFortune();
    }
}

板球教练

package com.aht.spring.entity.coach;

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

import com.aht.spring.entity.fortune.FortuneService;

@Component
public class CricketCoach implements Coach {

    private FortuneService fortuneService;

    public CricketCoach() {
        System.out.println("Default constructor");
    }

    @Autowired
    public void setFortuneService(FortuneService fortuneService) {
        this.fortuneService = fortuneService;
    }

    public String getDailyWorkOut() {
        return "Practice out field tips";
    }

    public String getDailyFortune() {
        return fortuneService.getFortune();
    }
}

棒球教练

package com.aht.spring.entity.coach;

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

import com.aht.spring.entity.fortune.FortuneService;

@Component
public class BaseBallCoach implements Coach {

    private FortuneService fortuneService;

    public String getDailyWorkOut() {
        return "Practice curve whole day";
    }

    public String getDailyFortune() {
        return fortuneService.getFortune();
    }

    @Autowired
    public void customAutoWire(FortuneService fortuneService) {
        this.fortuneService = fortuneService;
    }
}

我有三个 classes 用于执行三种自动接线方式,Constructor 和 Setter 工作正常,但是当 method 明智的自动接线完成时调用了错误的构造函数.我在 BaseBallCoach class 中错过的一件事是默认构造函数,但无论如何编译器会自动为我生成一个对吗?

这是我的CoachMethodInjectionApp.java,我在这里执行了方法自动连接

package com.aht.spring.app;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.aht.spring.entity.coach.Coach;

public class CoachMethodInjectionApp {

    public static void main(String[] args) {

        //  read config-file
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        //  get beans
        Coach coach = context.getBean("baseBallCoach", Coach.class);

        //  get dependencies
        System.out.println(coach.getDailyFortune());

        //  get daily workout
        System.out.println(coach.getDailyWorkOut());

        //  close context
        context.close();
    }
}

这是输出

Default constructor
Feel energetic for first half of trainning
Practice curve whole day

第一行输出是我不明白Default constructor,为什么CricketCoach的构造函数执行??

您正在此处创建 Coach class 的新实例: Coach coach = context.getBean("baseBallCoach", Coach.class); 每次创建新实例时,它都会执行一个构造函数。您在其中致电 System.out.println("Default constructor");。您可以尝试从 Cricket Coach imlpementation 中删除 @Component。

由于 CricketCoach class 用 @Component 注释并且当 Spring 容器启动时扫描包,它将创建类型 CricketCoach 的实例通过调用无参数构造函数

所有在 xml 文件中定义或用 @Component 注释或来自扫描包的 @Component 的任何扩展名的所有 bean 都将在 spring 的开始时间创建容器不管他们是否会被使用