什么是spring
spring是一个开源的框架,里面有一系列功能,可以使我们的开发变得更为轻松
简单来说,spring是包含众多工具方法的IoC容器
所谓容器,就是盛放东西的事务,例如我们的ArrayList就是数据存储的容器,我们的tomcat就是web容器
而IoC,其全称是Inversion of Control,也就是控制反转,下面用一个例子来介绍什么是控制反转
当我们要创建一个公寓,公寓中有一个个的房间,房间中有厕所。在代码中,我们这几个类实现中,想要将这几个类有所关联,就需要在apartment类中创建room类,在room类中创建wc类
但是,当我们要更改厕所的尺寸时,就需要在WC类的实现方法中加入参数size,但是这样做后,room类中实现也要加上size,apartment也要加上size
public class demo {
static class WC{
int size = 20;
public WC(int size){
this.size = size;
}
}
static class Room{
public Room(int size){
WC wc = new WC(size);
}
}
static class Apartment{
public Apartment(int size){
Room room = new Room(size);
}
}
public static void main(String[] args) {
Apartment apartment = new Apartment(30);
}
}
可以看到,这样的代码写法非常繁琐,耦合度非常的高,想要解决这个问题,我们就需要控制反转
我们将之前的apartment依赖room,room依赖wc的关系,转换为wc传入room,room传入apartment,这样的过程就称之为控制反转
例如下面代码
public class demo2 {
static class WC{
int size = 20;
public WC(int size){
this.size = size;
}
}
static class Room{
WC wc;
public Room(WC wc){
this.wc = wc;
}
}
static class Apartment{
Room room;
public Apartment(Room room){
this.room = room;
}
}
public static void main(String[] args) {
WC wc = new WC(30);
Room room = new Room(wc);
Apartment apartment = new Apartment(room);
}
}
而我们spring IoC,为了避免对象之间的依赖关系,我们将所有的对象都放到spring中,然后从spring中获取对象
有关IoC,还有一个概念——DI,全称是Dependency Injection,也就是依赖注入
当我们的对象之间有依赖关系,使用IoC可以将对象之间的依赖关系注入,实现解耦合
也就是说,IoC是一种思想,而DI是具体的实现方法
创建spring项目
和我们的maven项目一样,要创建一个maven项目
然后命名项目,点击finish即可
然后在pom.xml中添加spring有关的依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
</dependencies>
我们在项目中添加一个启动类,里面有main方法
存储bean对象
当我们创建一个类时
想要存储上面的这个user类在spring中,我们需要存储bean对象,也就是先创建bean对象,然后将bean对象存储在spring容器中
首先我们在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
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
然后我们将user对象存储到spring中,在beans中添加下面的代码片段
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="User" class="User"></bean>
</beans>
上面这个代码的意思是,我们将User类对象存储在spring容器中,如果我们的User类是在com.demo的包下,那么class应该写 class=“com.demo.User”,而id则是我们给这个类对象取的一个别名,方便以后取用
使用bean对象
首先在启动类中创建spring上下文,然后获取指定的bean对象
创建ApplilcationContext对象,里面的参数是我们的xml的名称,使用其getBean方法,传的参数是id,也就是我们起的别名
这时我们得到的是object对象,还需要强制转化一下
调用User对象的.hi方法,验证我们的对象是否获取成功
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//根据名称获取bean对象
User user = (User) context.getBean("user");
System.out.println(user.hi("xiaolock"));
我们还有另外一种方法来获取对象
context的getBean方法有多种重载方法,我们可以传入类对象,这样写可以避免强制类型转换
User user2 = context.getBean(User.class);
但是,这种如果使用上面的这种方法,我们如果在xml中存储多个User对象,就会出现报错
No qualifying bean of type ‘User’ available: expected single matching bean but found 2: user,anotherUser
还可以使用另一种重载方法,既传入id,也传入类对象
User user3 = context.getBean("user",User.class);
除了ApplicationContext外,还有另一种方法来得到bean对象——BeanFactory
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
User user4 = (User) factory.getBean("user");
其使用方法和ApplicationContext差不多,两者具体有下面几种区别
ApplicationContext和BeanFactory的区别
相同点
- 都可以都到spring上下文对象
- 都是来自spring的顶级接口
不同点
- ApplicationContext是BeanFactory的子类,ApplicationContext的功能更加齐全->资源访问,国际化,事件传播
- Application一次性加载所有bean对象,BeanFactory是需要哪个对象加载哪个对象,因此BeanFactory更加轻量化