1 官方资料
1.1 官网
1.2 进入 Spring5
下拉 projects, 进入 Spring Framework
进入 Spring5 的 github
1.3 在maven项目中导入依赖
<dependencies>
<!--加入spring开发的基本包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.8</version>
</dependency>
<!--加入spring开发切面编程需要的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.8</version>
</dependency>
</dependencies>
1.4 官方文档
2 Spring核心内容
上图说明:
3 Spring的几个重要概念
(1)Spring 可以整合其他的框架(Spring 是管理框架的框架)
(2)Spring 有两个核心的概念: IOC 和 AOP
(3)IOC(Inversion Of Control 反转控制)
- 传统的开发模式[JdbcUtils / 反射]
程序------>环境(程序读取环境配置,然后自己创建对象.)
解读:程序员编写程序, 在程序中读取配置信息;创建对象, new 或者 反射方式;使用对象完成任务
- IOC 的开发模式 [EmpAction EmpService EmpDao Emp]
程序<-----容器(容器创建好对象,程序直接使用.)
解读:
4 Spring快速入门
4.1 需求说明
4.2 实现步骤
(1)创建一个maven项目,在pom.xml文件中导入以下依赖
<dependencies>
<!--加入spring开发的基本包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.8</version>
</dependency>
<!--加入spring开发切面编程需要的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.8</version>
</dependency>
</dependencies>
(2) 创建 Moster 的javabean/entity,无参构造器一定要写
public class Monster {
private Integer monsterId;
private String name;
private String skill;
//全参构造器
public Monster(Integer monsterId, String name, String skill) {
this.monsterId = monsterId;
this.name = name;
this.skill = skill;
}
//无参构造器一定要写,Spring反射创建对象时,需要使用
public Monster() {
}
public Integer getMonsterId() {
return monsterId;
}
public void setMonsterId(Integer monsterId) {
this.monsterId = monsterId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
@Override
public String toString() {
return "Monster{" +
"monsterId=" + monsterId +
", name='" + name + '\'' +
", skill='" + skill + '\'' +
'}';
}
}
(3) 新建一个容器配置文件:鼠标右键目录名 --> new --> XML Configuration --> Spring Config,然后给配置文件取个名字,这里取beans(对于Maven项目XML文件通常在 src/main/resources
目录)
点击 创建 Spring facet ,然后点击确定
(4)在xml文件中配置Moster对象,在beans标签加入以下配置
注意:将class属性值修改为指定类的全路径
<!--
1. 配置monster对象/javabean
2. 在beans中可以配置多个bean
3. 一个bean表示就是一个java对象
4. class属性是用于指定类的全路径->spring底层使用反射创建
5. id属性表示该java对象在spring容器中的id, 通过id可以获取到对象
6. <property name="monsterId" value="100"> 用于给该对象的属性赋值
-->
<bean class="com.spring.bean.Monster" id="monster01">
<property name="monsterId" value="100"/>
<property name="name" value="牛魔王"/>
<property name="skill" value="芭蕉扇"/>
</bean>
<bean class="com.spring.bean.Monster" id="monster02">
<property name="monsterId" value="1001"/>
<property name="name" value="牛魔王~"/>
<property name="skill" value="芭蕉扇~"/>
</bean>
(5)新建一个测试类来获取容器中的对象
public class SpringBeanTest {
@Test
public void getMonster(){
//1. 创建容器 ApplicationContext
//2. 该容器和容器配置文件关联
ApplicationContext ioc =
new ClassPathXmlApplicationContext("beans.xml");
//3. 通过getBean获取对应的对象
// 默认返回的是Object , 但是运行类型Monster
//Object monster01 = ioc.getBean("monster01");
Monster monster01 = (Monster) ioc.getBean("monster01");
//4. 输出
System.out.println("monster01=" + monster01 + " 运行类型=" + monster01.getClass());
System.out.println("monster01=" + monster01 + "属性name=" + monster01.getName() +
" monserid=" + monster01.getMonsterId());
//5. 也可以在获取的时候,直接指定Class类型, 可以再次获取
Monster monster011 = ioc.getBean("monster01", Monster.class);
System.out.println("monster011=" + monster011);
System.out.println("monster011.name=" + monster011.getName());
//6. 查看容器注入了哪些bean对象,会输出bean的id
System.out.println("================================");
String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName=" + beanDefinitionName);
}
System.out.println("================================");
System.out.println("ok~~~");
}
}
运行结果:
4.3 注意事项
(1)该代码为什么读取到beans.xml文件
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
该代码通过类路径加载配置文件,可通过以下方式输出类加载路径
File f = new File(this.getClass().getResource("/").getPath());
System.out.println(f);
maven项目的类加载路径是:target\classes
(2)debug 看看 spring 容器结构/机制
(3) 当调用getBean(),方法获取对象时,会去beanDefinitionMap中去查找,如果发生该bean是单例的,就会返回 singletonobject 中初始化好了的对象,如果不是,就会动态的通过反射机制返回一个临时创建的对象
5 实现简单的基于XML配置的Spring
5.1 需求说明
5.2 思路分析
(1)使用xml的解析技术-Dom4j
(2)读取beans.xml
(3)解析得到monster对象的id,classpath,属性
(4)使用反射,创建对象
(5)放入到ioc容器(hashmap)
(6)提供一个getBean方法
5.3 实现步骤
(1)在maven项目中添加dom4j依赖
第一种方式:如果导入低版本(1.6.1),需要如下两个依赖
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>
第二种方式:如果导入高版本(2.0.0),需要如下一个依赖
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.0.0</version>
</dependency>
(2)实现容器类 WwjApplicationContext,java
注意:项目系统目录不能有中文,或者会找不到XML文件
package com.spring.wwjApplicationContext;
import com.spring.bean.Monster;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* 1. 这个程序用于实现Spring的一个简单容器机制
* 2. 这里实现如何将beans.xml文件进行解析,并生成对象,放入容器中
* 3. 提供一个方法 getBean(id) 返回对应的对象
*/
public class WwjApplicationContext {
private ConcurrentHashMap<String, Object> singletonObjects =
new ConcurrentHashMap<>();
//构造器
//接收一个容器的配置文件 比如 beans.xml, 该文件默认在resources
public WwjApplicationContext(String iocBeanXmlFile) throws Exception {
//1. 得到类加载路径
// String path = this.getClass().getClassLoader().getPath();
String path = this.getClass().getResource("/").getPath();
//2. 创建 Saxreader
SAXReader saxReader = new SAXReader();
//3. 得到Document对象
Document document =
saxReader.read(new File(path + iocBeanXmlFile));
//4. 得到rootDocument
Element rootElement = document.getRootElement();
//5. 得到第一个bean-monster01
Element bean = (Element) rootElement.elements("bean").get(0);
//6. 获取到第一个bean-monster01的相关属性
String id = bean.attributeValue("id");
String classFullPath = bean.attributeValue("class");
List<Element> property = bean.elements("property");
//遍历
Integer monsterId =
Integer.parseInt(property.get(0).attributeValue("value"));
String name = property.get(1).attributeValue("value");
String skill = property.get(2).attributeValue("value");
//7. 使用反射创建对象.=> 回顾反射机制
Class<?> aClass = Class.forName(classFullPath);
//这里o对象就是Monster对象
Monster o = (Monster) aClass.newInstance();
//给o对象赋值
o.setMonsterId(monsterId);
o.setName(name);
o.setSkill(skill);
//8. 将创建好的对象放入到singletonObjects
singletonObjects.put(id, o);
}
public Object getBean(String id) {
return singletonObjects.get(id);
}
}
(3)创建main类测试
package com.spring;
import com.spring.bean.Monster;
import com.spring.wwjApplicationContext.WwjApplicationContext;
public class AppMain {
public static void main(String[] args) throws Exception {
WwjApplicationContext ioc = new WwjApplicationContext("beans.xml");
Monster monster01 = (Monster)ioc.getBean("monster01");
System.out.println("monster01 = " + monster01);
}
}
运行结果:
6 Spring 原生容器底层结构