学JavaEE,一个不可缺的技术,就是spring框架。spring是一个开源的框架。要说spring是什么,它是一个包含了众多方法的IoC的容器。
初始spring
容器,是用来容纳某种物品的基本装置,比如Java中集合容器,包含了List等数据结构。Ioc,翻译过来,就是“控制反转”的意思。控制反转,指的是控制权的反转。平时我们写的代码,是自己来控制的,而使用spring,是将自己写的代码交给spring来控制。
IoC
现在有这样的业务:构建一辆车。车有车身,底盘,轮子。车身装在底盘上,底盘装上轮子。
public class Car {
public void init() {
Framework framework = new Framework();
framework.init();
}
}
public class Framework {
public void init() {
Bottom bottom = new Bottom();
bottom.init();
}
}
public class Bottom {
public void init() {
Tire tire = new Tire();
tire.init();
}
}
public class Tire {
private int size = 30;
public void init() {
System.out.println("size: " + size);
}
}
//测试
public class test {
public static void main(String[] args) {
Car car = new Car();
car.init();
}
}
要对代码进行改进,就会出现改动一处,改动整个代码的情况。整个过程,相当于是自己创造了“车”这个自己的产业链,在某处改动,相当的麻烦。使用下面的方式,就可以解决问题。
public class ioc {
static class Car {
private Framework framework;
public Car(Framework framework) {
this.framework = framework;
}
public void run() {
framework.init();
}
}
static class Framework {
private Bottom bottom;
public Framework(Bottom bottom) {
this.bottom = bottom;
}
public void init() {
bottom.init();
}
}
static class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
}
public void init() {
tire.init();
}
}
static class Tire {
private int size;
public Tire(int size) {
this.size = size;
}
public void init() {
System.out.println("轮胎:" + size);
}
}
public static void main(String[] args) {
Tire tire = new Tire(20);
Bottom bottom = new Bottom(tire);
Framework framework = new Framework(bottom);
Car car = new Car(framework);
car.run();
}
}
第一个代码中,类的创建是自上而下的,从车一直到轮子;而第二个代码中是把下级对象注入到当前的对象中,改变了上级对象,下级对象是不受影响的。第二个代码,实现了类的控制反转。
spring是一个包含了多个工具方法的IoC容器。它是一个容器,具备两个最基础的功能:将对象存到容器中;从容器中取出对象。对象的创建和销毁的权利交给了spring管理,本身又有存储对象和获取对象的能力。
DI
DI表示“依赖注入”。在Ioc容器运行的时候,动态地将某种依赖关系注入到对象中。实际上,它和IoC表示的是同样的内容:引入IoC容器。利用依赖关系注入的方式,实现对象之间的解耦。IoC是一种思想,DI就是这个思想的具体实现。
spring最重要的两个功能:存对象和取对象。
创建spring项目
创建普通Maven项目
创建普通Maven项目后,在Maven Repository中搜索Spring Context spring-context 及 spring-beans,添加到Maven中。Maven Repository: Search/Browse/Explore (mvnrepository.com)https://mvnrepository.com/(下载速度可能很慢,需要配置国内源。)
<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方法。
public class User {
public static void main(String[] args) {
//后序实现
}
}
Java中,对象叫做Bean。创建一个Bean对象(也是一个普通的类)。
public class UserBean {
public void sayBean() {
System.out.println("Hello, Bean!");
}
}
存储Bean对象到spring
创建xml文件,告诉spring,这个Bean对象需要托管给spring。xml文件需要在resources目录下创建。名字可以起为spring.xml。
xml文件复制以下配置。
<?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>
注册对象。
id表示标识,是用来取对象(Bean)使用,id写Bean对象;class是存储Bean的位置(包名+类名,没有包名,直接使用类名)。
从spring取出Bean对象
整个过程:在启动类中先获取spring上下文对象,从spring上下文对象中取出Bean对象,使用Bean。
public class User {
public static void main(String[] args) {
//1、获取spring上下文
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("spring.xml");
//2、从spring取出Bean对象
UserBean userBean = (UserBean) applicationContext.getBean("UserBean");
//3、使用Bean
userBean.sayBean();
}
}
ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象。
更简单的存储和读取Bean对象
上面的的配置文件的方法使用起来比较麻烦,可以使用更简单的方法来存储和读取Bean对象,使用注解。
使用注解,需要在spring.xml文件中新增配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="(项目的根目录)">
</content:component-scan>
</beans>
我们的结构是这样的:
创建一个包,叫component,将UserBean拖入到该包中。根路径写成component,就会扫描component以及子包(如果有)目录下所有的类。
在Bean对象中添加注解: