@ComponentScan 和@Component 背后的魔法
Magic behind @ComponentScan and @Component
我还在深入学习spring依赖注入。
我的第一个 class 是一个配置 class,我在其中声明容器加载和管理在注释方法中声明的 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();
}
}
我的第二个class是一个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 person class MyConfiguration:
MyDaoRepository(personList=[Person(name=Bagna, age=52, profession=Profession(name=professor,
description=professor in the university))])
我认为即使我没有要求,容器也会自动注入该对象。可能是编译器添加了一些@Autowired 注释。我不确定。
能否请您向我解释一下如何让 spring 容器不注入 bean,即使它们存在于容器中(例如 bean person),除非我要求进行注入由我自己使用@Autowired 注释。
原因是 spring 的集合自动装配和 lombok 的 Builder
的组合
首先,@Builder
添加一个全参数构造函数 MyDaoRepository(List<Person> list)
。
其次,spring 自动检测您的工厂方法 @Bean public Person person()
。
现在,由于构造函数需要一个集合,spring 将它可以找到的所有 Person
-bean 累积到 List
中并将其注入构造函数,相应地设置列表。
我认为(但目前未经测试但已记录 here),在这种情况下,将 @Autowired(required = false)
添加到 List<Person> persons
属性 是你想要的,因为将其标记为可选并且 spring 不会注入它。 (编辑:我错了,你仍然需要 no-args-constructor 才能工作,但是如果没有任何 @Autowired
注释,无论如何列表都不会以这种方式注入。 required=false
只是防止异常当找不到合适的 Person
bean 时。)
编辑:正如 Roddy 先生,冷冻豌豆的 Roddy 所指出的,也可以为 spring 添加一个不同的构造函数来创建你的 bean,例如通过使用 @NoArgsConstructor
注释您的存储库
我还在深入学习spring依赖注入。
我的第一个 class 是一个配置 class,我在其中声明容器加载和管理在注释方法中声明的 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();
}
}
我的第二个class是一个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 person class MyConfiguration:
MyDaoRepository(personList=[Person(name=Bagna, age=52, profession=Profession(name=professor, description=professor in the university))])
我认为即使我没有要求,容器也会自动注入该对象。可能是编译器添加了一些@Autowired 注释。我不确定。
能否请您向我解释一下如何让 spring 容器不注入 bean,即使它们存在于容器中(例如 bean person),除非我要求进行注入由我自己使用@Autowired 注释。
原因是 spring 的集合自动装配和 lombok 的 Builder
首先,@Builder
添加一个全参数构造函数 MyDaoRepository(List<Person> list)
。
其次,spring 自动检测您的工厂方法 @Bean public Person person()
。
现在,由于构造函数需要一个集合,spring 将它可以找到的所有 Person
-bean 累积到 List
中并将其注入构造函数,相应地设置列表。
我认为(但目前未经测试但已记录 here),在这种情况下,将 @Autowired(required = false)
添加到 List<Person> persons
属性 是你想要的,因为将其标记为可选并且 spring 不会注入它。 (编辑:我错了,你仍然需要 no-args-constructor 才能工作,但是如果没有任何 @Autowired
注释,无论如何列表都不会以这种方式注入。 required=false
只是防止异常当找不到合适的 Person
bean 时。)
编辑:正如 Roddy 先生,冷冻豌豆的 Roddy 所指出的,也可以为 spring 添加一个不同的构造函数来创建你的 bean,例如通过使用 @NoArgsConstructor