Spring学习(三)-- IoC 容器使用
1. 写在前面
在之前的一个小节中,我们了解了 IoC 容器的原理和设计思想。其核心就是 控制反转ROC 和 依赖注入DI。
在这个设计基础上,我们通过IOC容器来完成Bean 的创建和装配(这其中包含了大量的依赖注入相关工作),省去了程序员很多繁琐的工作。
那么一个 IOC 容器装配 Bean 的过程如何呢,下面我们看一下流程
2. 装配 Bean
这里给出了一个例子。
整个工程结构如下:
这里类的依赖关系为:
UserService 通过 setMailService() 方法注入了一个 MailService 对象
要装配一个 Bean,共分这么几步:
(1) 编写 application.xml 配置文件
注意这个配置文件在 resources 目录下,算作资源文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.itranswarp.learnjava.service.UserService">
<property name="mailService" ref="mailService" />
</bean>
<bean id="mailService" class="com.itranswarp.learnjava.service.MailService" />
</beans>
简单看一下这个配置文件,其他都是固定的。
我们关注一下, <bean>
的配置 :
-
<bean ..>
中 有一个id
标识,用来唯一标识 bean - 在
userService
Bean 中,通过<property name="..." ref="..."/>
注入了mailService
这个 Bean - Bean 的顺序无所谓
把这个配置文件加载的内容用代码写出来:
UserService userService = new Userservice();
MailService mailService = new MailService();
userService.setMailService(mailService);
同样,如果注入的不是 Bean,而是 boolean
、int
、'String' 这样的数据类型,则通过 value
注入,例如:
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="password" />
<property name="maximumPoolSize" value="10" />
<property name="autoCommit" value="true" />
</bean>
(2) 使用 IoC 容器创建 Bean
首先,创建Spring 的IoC 实例,让其加载配置文件。
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
之后,从容器中“取出”装配好的Bean使用:
// 获取 Bean:
UserService userService = context.getBean(UserService.class);
// 使用 Bean:
User user = userService.login("xxx.mail.com","password");
3. 使用 Annotation 配置
从上面可以看到,使用XML 文件,核心就是告诉 Spring 这些Bean 之间的依赖关系。
但是XML文件的编写非常麻烦。
这也是为什么在你自己的工程文件中没有看到这样的配置文件的原因
为了简化这个事情,我们这里还有一种方式,就是采用 Annotation 配置。这样可以让 Spring 自动扫描并且装配这些Bean。参考这里
(1)在类上添加注解
对之前的工程进行改造,删除XML配置文件,在对应的Bean添加相关的注解:
@Component
public class MailService {
···
}
@Component
注解 相当于定义了一个 Bean,这个 Bean 的名称默认为mailService
,即小写类名。
@Component
public class UserService{
@Autowired
MailService mailService;
}
这里使用了 @Component
和 @Autowired
两个注解,分别定义一个 Bean、完成注入。
(2)编写AppConfig类启动容器
@Configuration
@ComponentScan
public class AppConfig{
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
// 使用 Bean
User user = userService.login("bob@example.com", "password");
System.out.println(user.getName());
}
}
-
@Configuration
容器启动类需要标注@Configuration
,表明其是一个配置类,因为创建Spring IoC容器实例ApplicationContext
时候,使用了AnnotationConfigApplicationContext
实现类,其必须传入一个标注了@Configuration
的类。 -
@ComponentScan
这个注解,就是告诉 容器,去扫描该类所在的 包及其子包,创建所有带有@Component
注解的Bean,按照@Autowired
注入关系进行装配。
所以,应该按照如下的工程结构来组织:
Annotation 工程架构
总结
使用 Annotation 来完成Bean的创建和装配需要满足:
- 每个Bean 有
@Component
&Autowired
- 配置类 标注有
ComponentScan
&Configuration
- 所有Bean 都在配置类的包和子包内