阅读量:0
Spring 的基本概述
Spring学习的核心内容—一图胜千言
- IOC:控制反转,可以管理 Java 对象
- AOP:切面编程
- JDBCTemplate:是Spring提供一套访问数据库的技术,应用性强,相对好理解
- 声明式事务:基于IOC / AOP实现事务管理
Spring的几个重要概念
1、Spring可以整合其他的框架(Spring是管理框架的框架)
2、Spring有两个核心的概念:IOC和AOP
3、IOC(Inversion Of Control 控制反转)
- 传统的开发模式(JdbcUtils / 反射)
程序 —> 环境(程序读取环境配置,然后自己创建对象)
1、程序员编写程序,在程序中读取到配置信息
2、创建对象,new Object() // 反射方式
3、使用对象完成任务
- IOC的开发模式
程序 <— 容器(容器创建好对象,程序直接使用)
1、Spring 根据配置文件XML / 注解来创建对象,并放入到容器(ConcurrentHashMap)中,并且可以完成对象之间的依赖
2、当需要使用某个对象实例的时候,就直接从容器中获取即可
3、程序员可以更加关心如果使用对象完成相应的业务(以前是new => 注解 / 配置方式)
4、DI—Dependency Injection 依赖注入(是实现IOC的一种方法)
5、Spring最大的价值,通过配置给程序提供需要使用的web层[ Servlet(Action / Controller) ]/Service/Dao/[ JavaBean/Entity ]对象
- 这个是核心价值所在,也是IOC的具体体现,实现解耦
Spring的快速入门
需求说明
- 通过 Spring 的方式(配置文件),获取 JavaBean:Monster的对象,并给该对象属性赋值,输出该对象信息
完成步骤
- 下载Spring的开发包:https://spring.io/projects/spring-framework#learn
代码实现
<?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:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="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/util https://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 1. 配置monster对象 2. 在beans中可以配置多个bean 3. bean表示就是一个java对象 4. class属性是用于指定类的全路径 -> Spring底层使用反射创建 5. id属性表示该Java对象在Spring容器中的id,通过id可以获取到该对象 6. <property name="monsterId" value="100"/> 用于给该对象的属性赋值 --> <bean class="com.zan.spring.bean.Monster" id="monster01"> <!-- <bean class="com.zan.spring.bean.Monster">--> <property name="monsterId" value="100"/> <property name="name" value="牛魔王"/> <property name="skill" value="芭蕉扇"/> </bean> </beans>
public class SpringBeanTest { @Test public void getMonster() { // 1. 创建容器 ApplicationContext // 2. 该容器和容器配置文件是相关联的 - 读取到的是out文件夹下的beans.xml文件 ApplicationContext iocContext = new ClassPathXmlApplicationContext("beans.xml"); // 3. 通过getBean获取对应的对象(传入ID) // 默认返回的是Object,但是运行类型是Monster // Object monster01 = iocContext.getBean("monster01"); Monster monster01 = (Monster) iocContext.getBean("monster01"); // 4. 输出 System.out.println("monster01=" + monster01 + " 运行类型=" + monster01.getClass()); System.out.println("monster01=" + monster01 + " 获取对应的属性name=" + monster01.getName()); // 5. 也可以在获取的时候,直接指定Class类型,可以再次获取 Monster monster011 = iocContext.getBean("monster01", Monster.class); System.out.println("monster011=" + monster011); System.out.println("monster011.name=" + monster011.getName()); // 6. 查看容器注入了哪些bean对象,获取所有的beanName String[] beanDefinitionNames = iocContext.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); } System.out.println("ok~~~"); } // 验证类加载路径 @Test public void classPath() { File file = new File(this.getClass().getResource("/").getPath()); // 看到类的加载路径 System.out.println("file = " + file); // file = D:\Code\Java\Learn\Spring\spring-review\out\production\spring-review } }
Debug查看Spring容器结构/机制
手动开发 - 简单的Spring基于XML配置的程序
需求说明
- 自己写一个简单的Spring容器, 通过读取beans.xml,获取第1个JavaBean:Monster的 对象,并给该的对象属性赋值,放入到容器中, 输出该对象信息
- 也就是不使用 Spring 的原生框架,我们自己简单模拟实现
需求分析
代码实现
1、导入 Dom4j.jar 包
2、编写ZanApplicationContext
public class ZanApplicationContext { private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>(); // 构造器 // 接受一个容器的配置文件,比如 beans.xml public ZanApplicationContext(String iocBeanXmlPath) throws Exception { // 1. 得到类加载路径 String path = this.getClass().getResource("/").getPath(); // 2. 创建SAXReader SAXReader saxReader = new SAXReader(); // 3. 获取文档Document对象 Document document = saxReader.read(new File(path + iocBeanXmlPath)); // 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"); // 遍历 // for (Element element : property) { // String value = element.attributeValue("value"); // System.out.println(value); // } // 这里简便获取 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); // 获取对应的class对象 // 这是的o对象就是一个Monster对象 Monster o = (Monster) aClass.newInstance(); // 给o对象赋值 // 使用反射赋值 // Method[] declaredMethods = aClass.getDeclaredMethods(); // for (Method declaredMethod : declaredMethods) { // Object invoke = declaredMethod.invoke(o); // // } o.setMonsterId(monsterId); o.setName(name); o.setSkill(skill); // 8. 将创建好的对象放入到singleObjects中 singletonObjects.put(id, o); } public Object getBean(String id) { // 还可以严谨一下 return singletonObjects.get(id); } }
- Test类
public class ZanApplicationContextTest { public static void main(String[] args) throws Exception { ZanApplicationContext zanApplicationContext = new ZanApplicationContext("beans.xml"); Monster monster01 = (Monster) zanApplicationContext.getBean("monster01"); System.out.println(monster01); } }
Spring原生容器底层结构
补充:可以不进行分配ID,系统会默认分配ID,分配ID的规则为全类名#1,全类名#1 …