在 Spring 概述中说到,Core 模块是 IOC 容器,解决对象创建和之间的依赖关系。
下面就来说说如何得到 IOC 容器,通过 IOC 容器来创建对象、解决对象之间的依赖关系。
Spring 容器不单单只有一个,可以归为两种类型
- Bean 工厂,BeanFactory
- 加载 Spring 配置文件
- 通过 XmlBeanFactory + 配置文件来创建 IOC 容器
//加载Spring的资源⽂件
Resource resource = new ClassPathResource("applicationContext.xml");
//创建IOC容器对象【IOC容器=⼯⼚类+applicationContext.xml】
BeanFactory beanFactory = new XmlBeanFactory(resource);
- 应用上下文,ApplicationContext
- 直接通过 ClassPathXmlApplicationContext 对象来获取
// 得到IOC容器对象
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(ac);
Spring 常见的配置对象方式
- 使⽤XML⽂件配置
- 使⽤注解来配置
- 使⽤JavaConfig来配置
上面已经有了得到 IOC 容器对象了。接下来是在 applicationContext.xml 文件中配置信息。
首先有一个 JavaBean 的类。
public class User {
private String id;
private String username;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
现在我们有了IOC容器,可以让IOC容器帮我们创建对象了。在applicationContext.xml⽂件中配置对应
的信息就⾏了
通过IOC容器对象获取对象:在外界通过IOC容器对象得到User对象
// 得到IOC容器对象
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) ac.getBean("user");
System.out.println(user);
上⾯我们使⽤的是IOC通过⽆参构造函数来创建对象,我们来回顾⼀下⼀般有⼏种创建对象的⽅式:
- ⽆参构造函数创建对象
- 带参数的构造函数创建对象
- ⼯⼚创建对象
- 静态⽅法创建对象
- ⾮静态⽅法创建对象
使⽤⽆参的构造函数创建对象我们已经会了,接下来我们看看使⽤剩下的IOC容器是怎么创建对象的。
带参数的构造函数创建对象首先 JavaBean 需要提供有参构造器
public User(String id, String username) {
this.id = id;
this.username = username;
}
下面是配置applicationContext.xml
工厂方法创建对象
⾸先,使⽤⼀个⼯⼚的静态⽅法返回⼀个对象
public class Factory {
public static User getBean() {
return new User();
}
}
配置文件中使用工厂的非静态方法返回对象
注解方式
通过注解来配置信息就是为了简化IOC容器的配置,注解可以把对象添加到IOC容器中、处理对象依赖
关系,我们来看看怎么⽤吧:
使⽤注解步骤:
1)先引⼊context名称空间
xmlns:context="http://www.springframework.org/schema/context"
2)开启注解扫描器
第⼆种⽅法:也可以通过⾃定义扫描类以@CompoentScan修饰来扫描IOC容器的bean对象。
如下代码:
//表明该类是配置类
@Configuration
//启动扫描器,扫描bb包下的
//也可以指定多个基础包
//也可以指定类型
@ComponentScan("bb")
public class AnnotationScan {
}
在使⽤@ComponentScan()这个注解的时候,在测试类上需要@ContextConfiguration这个注解来加载
配置类…
- @ContextConfiguration这个注解⼜在Spring的test包下…
- 创建对象以及处理对象依赖关系,相关的注解:
- @ComponentScan扫描器
- @Configuration表明该类是配置类
- @Component 指定把⼀个对象加⼊IOC容器—>@Name也可以实现相同的效果【⼀般少⽤】
- @Repository 作⽤同@Component; 在持久层使⽤
- @Service 作⽤同@Component; 在业务逻辑层使⽤
- @Controller 作⽤同@Component; 在控制层使⽤
- @Resource 依赖关系
- 如果@Resource不指定值,那么就根据类型来找,相同的类型在IOC容器中不能有两个
如果@Resource指定了值,那么就根据名字来找
在各个层中使用对应的注解,即可完成对象的配置。
通过 JavaConfig 方式- 编写⼀个java类,使⽤@Configuration修饰该类
- 被@Configuration修饰的类就是配置类
@org.springframework.context.annotation.Configuration
public class Configuration {
}
使⽤配置类创建bean:
- 使⽤@Bean来修饰⽅法,该⽅法返回⼀个对象。
- 不管⽅法体内的对象是怎么创建的,Spring可以获取得到对象就⾏了。
- Spring内部会将该对象加⼊到Spring容器中
- 容器中bean的ID默认为⽅法名
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean
public UserDao userDao() {
UserDao userDao = new UserDao();
System.out.println("我是在configuration中的"+userDao);
return userDao;
}
}
测试代码:要使⽤@ContextConfiguration加载配置类的信息
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
//加载配置类的信息
@ContextConfiguration(classes = Configuration.class)
public class Test2 {
@Test
public void test33() {
ApplicationContext ac =
new ClassPathXmlApplicationContext("bb/bean.xml");
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao);
}
}
IOC 容器的原理
IOC容器其实就是⼀个⼤⼯⼚,它⽤来管理我们所有的对象以及依赖关系。
- 原理就是通过Java的反射技术来实现的!通过反射我们可以获取类的所有信息(成员变量、类名等
- 等等)!
- 再通过配置⽂件(xml)或者注解来描述类与类之间的关系
- 我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了!
- 根据Bean配置信息在容器内部创建Bean定义注册表
- 根据注册表加载、实例化bean、建⽴Bean与Bean之间的依赖关系
- 将这些准备就绪的Bean放到Map缓存池中,等待应⽤程序调⽤



