Spring Autowiring вызывает неправильный конструктор - PullRequest
3 голосов
/ 26 марта 2019

Я учу Springs с аннотациями и авто-проводкой. Я пробовал три типа авто проводки

  1. Конструктор
  2. Сеттер впрыска
  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();
}

FortuneService

package com.aht.spring.entity.fortune;

public interface FortuneService {

    String getFortune();
}

HappyFortuneService

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";
    }
}

FootBallCoach

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();
    }
}

CricketCoach

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();
    }
}

BaseBallCoach

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;
    }
}

У меня есть три класса для выполнения трех способов автоматического подключения, Constructor и Setter работали нормально, но когда было выполнено мудрое автоматическое подключение method, был вызван неправильный конструктор. Одна вещь, которую я пропустил в своем классе BaseBallCoach, была конструктором по умолчанию, но в любом случае компилятор автоматически сгенерирует его для меня, верно?

Это мой 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 выполняет ??

Ответы [ 2 ]

6 голосов
/ 26 марта 2019

Поскольку класс CricketCoach помечен @Component, и пакет сканируется при запуске контейнера Spring, он создает экземпляр типа CricketCoach, вызывая конструктор no-arg

Все bean-компоненты, определенные в xml-файле или помеченные @Component или любым расширением @Component из отсканированных пакетов, будут созданы во время запуска контейнера Spring независимо от того, будут они использоваться или нет

1 голос
/ 26 марта 2019

Вы создаете новый экземпляр класса Coach здесь: Coach coach = context.getBean("baseBallCoach", Coach.class); Каждый раз, когда создается новый экземпляр, он выполняет конструктор.В котором у вас есть звонок на System.out.println("Default constructor");.Вы можете попробовать удалить @Component из Cricket Coach.

...