Магия позади @ComponentScan и @Component - PullRequest
2 голосов
/ 03 июля 2019

Я все еще изучаю внедрение пружинных зависимостей в глубину.

Мой первый класс - это класс конфигурации, где я объявляю контейнеру загрузить и управлять bean-компонентами, объявленными в аннотированных методах.

package ioc.question_004;

import ioc.commun.Person;
import ioc.commun.Profession;
import org.springframework.context.annotation.*;

@Configuration
public class MyConfiguration {

    @Bean
    public Profession profession(){
        return Profession.builder()
                     .name("professor")
                     .description("professor in the university")
                     .build();
    }

    @Bean
    public Person person(){
        return Person.builder()
                     .name("Bagna")
                     .age(52)
                     .profession(profession())
                     .build();
    }

}

Мой второй класс - daoRepository, он выглядит следующим образом:

package ioc.question_008.dao;

import ioc.commun.Person;
import lombok.*;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
@Builder
@Setter
@Getter
@EqualsAndHashCode
@ToString
public class MyDaoRepository implements dao {

    List<Person> personList = new ArrayList<>();

    @Override
    public boolean save( Person person ){
        return this.personList.add(person);
    }

    @Override
    public boolean delete( Person person ){
        return  this.personList.remove(person);
    }

}

Мой рабочий код выглядит следующим образом:

@Configuration
@Import(MyConfiguration.class)
@ComponentScan(basePackageClasses = {MyDaoRepository.class} )
public class DependencyInjection {
    public static void main( String[] args ) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DependencyInjection.class);
        dao myDaoRepository = (MyDaoRepository) context.getBean("myDaoRepository");
        System.out.println(myDaoRepository);
    }

}

Магически MyDaoRepository содержит лицо @Bean, объявленное вкласс конфигурации MyConfiguration:

MyDaoRepository (personList = [Person (имя = Bagna, возраст = 52, профессия = профессия (имя = профессор, описание = профессор в университете))])

Я думаю, что контейнер автоматически вводит этот объект, даже если я этого не просил.Может быть, некоторые аннотации @Autowired добавлены компилятором.Я не уверен.

Не могли бы вы объяснить, как я могу попросить пружинный контейнер не вводить бобы, даже если они существуют в контейнере (например, бобовому человеку), если я не прошусделайте инъекцию самостоятельно с аннотацией @Autowired.

1 Ответ

7 голосов
/ 03 июля 2019

Причиной является комбинация весенней автопроводки коллекций и ломбоков Builder

Сначала @Builder добавляет конструктор всех аргументов MyDaoRepository(List<Person> list).

Во-вторых, пружина автоматически определяет ваши фабричные методы @Bean public Person person().

Теперь, поскольку конструктор ожидает коллекцию, spring собирает все Person -бины, которые он может найти, в List и внедряет его в конструктор, устанавливая список соответствующим образом.

Я думаю (но в настоящее время это не проверено, но задокументировано здесь ), что добавление @Autowired(required = false) к вашему List<Person> persons свойству - это то, что вы хотите в этом случае, так как это помечает его как необязательное, а spring будет не вводить это. (РЕДАКТИРОВАТЬ: я ошибся, вам все еще нужен конструктор no-args, чтобы это работало, но без каких-либо аннотаций @Autowired список так и не был бы введен таким образом. 1023 * боб найден.)

РЕДАКТИРОВАТЬ: Как отметил г-н Родди, Родди из замороженного гороха, также было бы возможно добавить другой конструктор для весны, чтобы создать ваш боб, например, аннотируя ваш репозиторий @NoArgsConstructor

...