环境说明
- JDK 17
- Spring 6.0.6
配置Bean和依赖注入
首先创建一个配置类来替代配置文件,用以编写 IOC 容器的相关配置:
@Configuration
public class MainConfig {
}
然后通过 AnnotationConfigApplicationContext 创建并初始化 IOC 容器(加上配置类):
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
}
然后在配置类中配置 Bean :
@Configuration
public class MainConfig {
@Bean("student") // @Bean注解中还可以配置name、initMethod 等属性
// @Bean
// @Lazy(true) //对应lazy-init属性
// @Scope("prototype") //对应scope属性
// @DependsOn("teacher") //对应depends-on属性
public Student getStudent(Teacher teacher){
return new Student(teacher);
}
}
主方法中获取调用 Bean :
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Student student = context.getBean(Student.class);
student.hello();
}
当需要依赖注入时可以直接在 Bean 的形参列表中或者在方法体中注入属性值,更好的方式是直接在 Bean 对应的类里通过注解注入依赖:
public class Student {
@Autowired
private Teacher teacher;
@Autowired 注解可以对成员变量、方法和构造方法进行注释,但是不同的使用方式注入的具体实现并不同:
- @Autowired写在成员变量上,相当于在配置文件中配置bean,并且使用setter注入。
- @Autowired写在构造方法上,相当于使用构造方法进行依赖注入。
@Autowired 注解默认根据类型进行自动装配,如果出现多个同类型的Bean,可以使用@Qualifier 注解指定特定的 Bean:
public class Student {
@Autowired
@Qualifier("kk") //匹配名称为kk的Teacher类型的Bean
private Teacher teacher;
和@Autowired注解功能类似的注解@Resource,默认根据名称进行自动装配,如果需要使用该注解要额外导入对应依赖:
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
@Resource 和 @ Autowired 注解的主要区别如下:
- @Resource默认 ByName如果找不到则 ByType,可以添加到set方法、字段上。
- @Autowired默认是 ByType,只会根据类型寻找,可以添加在构造方法、set方法、字段、方法参数上。
前面是使用@Bean注解的方式来注册Bean,但是这样还不够方便,实际上可以让容器通过反射直接获取构造方法去生成 Bean:可以在需要注册为Bean 的类上添加 @Component 注解
@Component
public class Student {
然后在配置类上添加包扫描
@Configuration
@ComponentScan("com.example.bean")
public class MainConfig {
这样Spring在扫描对应包下所有的类时,会自动将那些添加了@Component的类注册为Bean。但是这种方式只适用于我们自己编写的类,如果是第三方包提供的类,还是需要使用 @Bean 注册的方式注册Bean。
对于通过@Bean和@Component形式注册的Bean,Spring都会默认为其添加一个name属性,通过@Bean注册的 Bean默认名称是对应的方法名称如 getStudent
,通过@Component注册的Bean默认名称是以首字母小写的驼峰命名法命名的类名如 student
。