Spring5基本介绍
官方资料
官网
https://spring.io/
Spring5下载
1.进入该网站
https://repo.spring.io
2.找到Artifacts

3.点开release

4.在release中找到org下的 springframework

5.然后找到spring,右侧会出现下载地址 https://repo.spring.io/ui/native/release/org/springframework/spring/

6.找到需要的版本进行下载


(离线文档也在里面)
在线文档
https://docs.spring.io/spring-framework/docs/current/reference/html/
核心内容

- Spring 核心学习内容 IOC、AOP、jdbcTemplate、声明式事务。
- IOC:控制反转,可以管理 java 对象。(重难点)
- AOP:切面编程。(重难点)
- JDBCTemplate:是 spring 提供一套访问数据库的技术,应用性强,相对好理解。
- 声明式事务:基于 ioc/aop 实现事务管理。
重要概念
- Spring 可以整合其他的框架(Spring是管理框架的框架)。
- Spring 有两个核心的概念:IOC 和 AOP。
- IOC [Inversion Of Control 反转控制]
- DI—Dependency Injection 依赖注入,可以理解成是 IOC 的另外叫法。
- Spring 最大的价值,通过配置,给程序提供需要使用的web 层[Servlet(Action/Controller)]/Service/Dao/[JavaBean/entity]对象,这个是核心价值所在,也是 IOC 的具体体现,实现解耦。

传统的开发模式

- 程序员编写程序,在程序中读取配置信息。
- 创建对象, new Object()//反射
- 使用对象完成任务
IOC 的开发模式 [EmpAction EmpService EmpDao Emp]
容器---->程序 //容器创建好对象,程序直接使用。

- Spring 根据配置文件 xml/注解,创建对象, 并放入到容器(ConcurrentHashMap等)中,并且可以完成对象之间的依赖。
- 当需要使用某个对象实例的时候,就直接从容器中获取即可。
- 程序员可以更加关注如何使用对象完成相应的业务。(以前是 new ... ==> 注解/配置 方式)
- DI—Dependency Injection 依赖注入,可以理解成是 IOC 的另外叫法。
- Spring 最大的价值,通过配置,给程序提供需要使用的 web 层[Servlet(Action/Controller)]/Service/Dao/[JavaBean/entity]对象,这个是核心价值所在,也是 ioc 的具体体现,实现解耦。
快速入门
需求说明
通过 Spring 的方式[配置文件],获取 JavaBean: Monster 的对象,并给该的对象属性赋 值,输出该对象信息。
注意:创建好java工程后,要引入相关的spring5基本包


代码实现
package com.lzw.spring.bean;
public class Monster {
private Integer monsterID;
private String name;
private String skill;
//无参构造器一定要写,Spring反射创建对象时需要使用
public Monster() {
}
public Monster(Integer monsterID, String name, String skill) {
this.monsterID = monsterID;
this.name = name;
this.skill = skill;
}
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 + '\'' +
'}';
}
}
创建spring的配置文件





<!--
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.lzw.spring.bean.Monster" id="monster01">
<property name="monsterID" value="100"/>
<property name="name" value="牛魔王"/>
<property name="skill" value="蛮牛冲撞"/>
</bean>
<bean class="com.lzw.spring.bean.Monster" id="monster02">
<property name="monsterID" value="1001"/>
<property name="name" value="牛魔王~"/>
<property name="skill" value="芭蕉扇~"/>
</bean>
获取Monster对象
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 monster02 = ioc.getBean("monster01", Monster.class);
System.out.println("monster02=" + monster02 + " 运行类型=" + monster02.getClass());
System.out.println("monster02=" + monster02 + "属性name=" + monster02.getName());
}
注意事项和细节
1.怎么读取到了 beans.xml
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
读取的是out目录
File file = new File(this.getClass().getResource("/").getPath());
System.out.println(file);//E:\VIP\AllDemo\Spring5\spring\out\production\spring
2.debug查看spring容器结构
注意:配置debugger








3.查看容器注入了哪些bean对象
String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}

手动实现简单的Spring基于xml配置的程序
需求说明
自己写(模拟)一个简单的 Spring 容器,通过读取 beans.xml,获取第 1 个 JavaBean: Monster 的 对象,并给该的对象属性赋值,放入到容器中,输出该对象信息。
思路分析

代码实现
记得导入dom4j包。beans.xml ,Monster.java 和上文中的一样。
package com.lzw.spring.lzwapplicationcontext;
import com.lzw.spring.bean.Monster;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author LiAng
* 1. 这个程序用于实现Spring的一个简单容器机制
* 2. 后面我们还会详细实现
* 3. 这里我们实现如何将beans.xml文件进行解析,并生成对象,放入容器中
* 4. 提供一个方法 getBean(id) 返回对应的对象
* 5. 这里仅仅只是理解Spring容器的机制
*/
public class LzwApplicationContext {
private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();
//构造器
//接收一个容器的配置文件 比如 beans.xml, 该文件默认在src
public LzwApplicationContext(String iocBeanXmlFile) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException {
//1. 得到类加载路径
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);
Monster o = (Monster) aClass.newInstance();
//给o对象赋值
//反射来赋值=> 这里简化,直接赋值->目的就是先理解流程
//这里的方法就是setter方法
//Method[] declaredMethods = aClass.getDeclaredMethods();
//for (Method declaredMethod : declaredMethods) {
// declaredMethod.invoke();
//}
o.setMonsterID(monsterID);
o.setName(name);
o.setSkill(skill);
//8. 将创建好的对象放入到singletonObjects
singletonObjects.put(id, o);
}
public Object getBean(String id) {
return singletonObjects.get(id);
}
}
public static void main(String[] args) throws DocumentException, IllegalAccessException, InstantiationException, ClassNotFoundException {
LzwApplicationContext ioc = new LzwApplicationContext("beans.xml");
Object bean = ioc.getBean("monster01");
System.out.println(bean);
}

Spring 原生容器底层结构

作业
在 beans.xml 中,我们注入 2 个 Monster 对象,但是不指定 id,如下

(1)运行会不会报错
答:不会报错,会正常运行。
(2)如果不报错,你能否找到分配的 id,并获得到该对象。
答:系统会默认分配 id,分配 id 的规则是 全类名#0 , 全类名#1。
Monster monster01 = (Monster)ioc.getBean("com.lzw.spring.bean.Monster#0");
