@ComponentScan和@Component背后的魔力

zak*_*zak 2 java spring autowired spring-ioc

我仍在深入学习spring依赖注入。

我的第一个类是配置类,在这里我向容器声明以加载和管理在带注释的方法中声明的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();
    }

}
Run Code Online (Sandbox Code Playgroud)

我的第二个类是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);
    }

}
Run Code Online (Sandbox Code Playgroud)

我的运行代码如下:

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

}
Run Code Online (Sandbox Code Playgroud)

神奇的是MyDaoRepository包含在配置类MyConfiguration中声明的@Bean人:

MyDaoRepository(personList = [人员(名称= Bagna,年龄= 52,专业=专业(名称=教授,描述=大学教授))]))

我想,即使我没有要求,容器也会自动注入该对象。可能是编译器添加了@Autowired批注。我不确定。

能否请我解释一下,即使我在容器中(例如,豆人),我也可以要求弹簧容器不注入豆子,除非我要求自己使用@Autowired批注进行注入。

sfi*_*iss 7

原因是春季的自动装配系列和龙目岛的 Builder

首先,@Builder添加一个all args构造函数MyDaoRepository(List<Person> list)

其次,spring自动检测您的工厂方法@Bean public Person person()

现在,由于构造函数需要一个集合,因此spring Person会将其可以找到的所有-bean 累积到a中,List然后将其注入到构造函数中,并相应地设置列表。

我认为(但目前尚未测试,但已在此处进行了记录),在这种情况下,您需要添加@Autowired(required = false)List<Person> persons属性中,因为将其标记为可选,并且spring不会注入它。(编辑:我错了,您仍然需要no-args-constructor来使其工作,但是没有任何@Autowired注释,无论如何该列表都不会以这种方式注入。required=false当找不到合适的Personbean 时,这可以防止异常。)

编辑:正如冷冻豌豆的罗迪·罗迪先生所指出的那样,还可以为spring添加一个不同的构造函数来创建您的bean,例如,通过使用 @NoArgsConstructor