spring的概述
1. spring 的 开源的轻量级框架
2. spring的两大核心:IOC ,AOP
耦合和解耦
1. 什么是耦合
模块之间的关联程度, 依赖程度
2. 什么是解耦
降低模块之间的耦合度(依赖关系)
3. 解耦的目的
编译器不依赖,运行期才依赖
4. 解耦思路
1)把全限类名都放到配置文件中
2) 通过工厂帮助创建对象
当是我们讲解 jdbc 时,是通过反射来注册驱动的,代码如下: Class.forName("com.mysql.jdbc.Driver");//此处只是一个字符串 此时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除 mysql 的驱动 jar 包,依然可以编译(运 行就不要想了,没有驱动不可能运行成功的)。
控制反转-- 自定义IOC
1.接口及接口实现类
2. 配置文件
<beans>
<!--
用bean标签配置所有的bean对象
id: 对象的唯一的标志
class:类名
-->
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl2"></bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>
3. 创建BeanFactory工厂对象
package com.itheima.factory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/* 创建bean对象的工厂类
*/
public class BeanFactory {
private static Map<String ,Object> map = new HashMap<>();
//提前把所有的对象创建出来,存储 //Map :因为有查找需求 --相当于容器对象-- 包含了所有的对象
//静态代码块 编译时创建
// 有些代码需要在项目启动的时候就执行
// 一个项目启动需要加载的很多配置文件等资源,我们就可以都放入静态代码块中
static{ //获取配置文件的输入流对象
InputStream inputStream = BeanFactory.class.getResourceAsStream("/beans.xml");
SAXReader reader = new SAXReader();//解析xml获取xml中所有的信息
try {
Document doc = reader.read(inputStream);//创建文档对象
Element root = doc.getRootElement();//获取根节点
//获取根节点中所有的子节点//element("bean") : 获取第一个叫bean的子节点
//elements("bean") : 获取所有叫bean的子节点//elements() : 获取所有的子节点
List<Element> beanList = root.elements("bean");//获取每一个bean的id和class
for (Element element : beanList) {
String id = element.attributeValue("id");
String className = element.attributeValue("class");
//通过className全限类名创建对象--获取字节码
Class clazz = Class.forName(className);
Object obj = clazz.newInstance(); //无参构造一个对象//通过反射创建对象
//存储在Map集合中 //key: id //value:obj
map.put(id ,obj);
}
} catch (Exception e) { e.printStackTrace(); }
}//需要实现的功能,传入一个名字,获取一个Bean对象
public static Object getBean(String name){
return map.get(name); // 根据名字取出对象
}
}
4. 测试
package com.itheima;
import com.itheima.factory.BeanFactory;
public class TestCustomIOC {
public static void main(String[] args) {
// 静态方法 通过类直接调用
Object userService1 = BeanFactory.getBean("userService");
System.out.println(userService1);
Object userService2 = BeanFactory.getBean("userService");
System.out.println(userService2);
}
}
5.执行结果
com.itheima.service.impl.UserServiceImpl@2bbf4b8b
com.itheima.service.impl.UserServiceImpl@2bbf4b8b
Process finished with exit code 0
上一小节我们通过使用工厂模式,实现了表现层——业务层以及业务层——持久层的解耦。 它的核心思想就是:
1、通过读取配置文件反射创建对象。
2、把创建出来的对象都存起来,当我们下次使用时可以直接从存储的位置获取。
这里面要解释两个问题:
第一个:存哪去? 分析:由于我们是很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。 到底选 Map 还是 List 就看我们有没有查找需求。有查找需求,选 Map。 所以我们的答案就是 在应用加载时,创建一个 Map,用于存放三层对象。 我们把这个 map 称之为容器。
第二个:什么是工厂? 工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。 原来: 我们在获取对象时,都是采用 new 的方式。是主动的。
明确 ioc(inversion of control)的作用: 削减计算机程序的耦合(解除我们代码中的依赖关系)。
以上为自定义IOC,以下为Spring的IOC
============================================================================
Spring的IOC入门(掌握)
1.引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
2.创建接口和实现类
3. 创建beans.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
http://www.springframework.org/schema/beans: 引入bean的名称空间
约束:现在xml的书写
dtd:mybatis
schema:spring
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd 引入约束
-->
<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="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>
4. 创建容器对象,根据id获取对象
package com.itheima;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class TestSpringIOC {
public static void main(String[] args) {
//创建spring的IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
//获取对象
Object userDao = ac.getBean("userDao"); // 获取对象
System.out.println(userDao);
Object userService = ac.getBean("userService"); //到配置文件获取对象
System.out.println(userService);
}
}
根据配置文件中的id取出对应接口对象。
5.执行结果
com.itheima.dao.impl.UserDaoImpl@10d68fcd
com.itheima.service.impl.UserServiceImpl@117e949d
Process finished with exit code 0
IOC的细节
1、容器对象的类结构图
a、beanFactory 是spring容器的顶层接口
b、接口ApplicationContext是 beanFactory子接口
实现类:ClassPathXmlApplicationContext -- 从类路径之下读取配置文件 (常用)
FileSystemXmlApplicationContext - 从绝对路径指定的配置文件读取
AnnotationConfigApplicationContext -- 纯注解配置使用的类 (常用)
c、BeanFactory与ApplicationContext区别
//ApplicationContext:在创建容器时只创建单例模式的对象
// 多例模式的对象,在获取时创建
2、getBean方法(掌握) 配置文件默认 applicationContext.xml
3、bean对象的范围和生命周期(掌握)
springIOC容器默认的单例模式: 单例模式的对象在创建容器时创建,销毁容器时销毁
scope:prototype 原型模式(多例模式):获取时创建,当对象长时间不在被引用, 则被垃圾回收机制回收
scope:singleton :单例模式 默认
scope :request: 请求范围
scope: session : 回话范围
单例模式在
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
就已经创建对象了
ac.close();
的时候销毁。
多例模式需在获取创建,长时间不用时回收销毁。
=======================================================================================
4、实例化bean的三种方法
=====================================================================
1 .<bean id="name" class="全限类名">
getBean(name)
============================================================================
2. 根据静态工厂获取对象
/**
* 通过静态工厂获取对象
*/
public class StaticFactory {public static UserDao getUserDao(){
return new UserDaoImpl();
}
}<!--通过静态工厂创建UserDao对象-->
<!--
factory-method: 工厂方法,返回UserDao对象的方法名
-->
<bean id="userDao" class="com.itheima.factory.StaticFactory" factory-method="getUserDao"></bean>
<!--通过静态工厂创建UserDao对象-->
<!--
factory-method: 工厂方法,返回UserDao 对象的方法名
-->
==========================================================================================
3. 根据实例(非静态)工厂获取对象
/**
* 实例工厂创建对象
*/
public class InstanceFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}<!--创建实例工厂对象-->
<bean id="instanceFatory" class="com.itheima.factory.InstanceFactory"></bean>
<!--通过实例工厂创建UserDao对象-->
<bean id="userDao2" factory-bean="instanceFatory" factory-method="getUserDao"></bean>
===============================================================================================
5、依赖注入(掌握)
a.什么是依赖注入
业务层需要持久层的对象,在配置文件中给业务层传入持久层的对象,就是依赖注入
b. ioc
控制反转包含了依赖注入和依赖查找
=====================================================================================
A、构造方法注入(掌握) <constructor-arg>标签 需构造方法
value属性只能赋值简单类型
ref: pojo类型,复杂类型, 关联创建好的对象
========================================================================================
B、set方法注入属性(常用)(掌握) <property>标签 需set方法 比较常用(因为构造方法中有有参构造方法,必须就要有无参构造方法)
==================================================================================
C、p名称空间注入:基于set方法注入--- 了解
a、在头部文件中引入p名称空间
b、使用p名称空间注入属性
<bean id="user3" class="com.itheima.domain.User"
p:id="5" p:username="马汉" p:sex="男" p:birthday-ref="birthday" >
</bean>
=========================================================================================
D、注入集合属性(掌握)
array ,list ,set 结构相同,标签可以混用
<!--map集合properties结构相同,可以通用-->
spring第一天
spring介绍
spring 轻量级框架
两个核心:IOC 控制反转 包括依赖注入和依赖查找 , 主要作用:降低耦合度
AOP:面向切面编程
耦合和解耦
springIOC的入门
1)引入依赖
spring-context-5.0.2.RELEASE.jar
spring-core-5.0.2.RELEASE.jar
spring-aop-5.0.2.RELEASE.jar
spring-beans-5.0.2.RELEASE.jar
spring-expression-5.0.2.RELEASE.jar
2) 配置文件:beans.xml applicationContext.xml
创建对象 <bean/>
3) 测试
创建容器对象
从容器中获取对象:getBean("id | name") getBean(Class) , getBean("id | name", Class )
容器对象的类结构图
BeanFactory:
ApplicationContext:在创建容器时创建单例模式的对象
多例模式的对象在使用时创建对象
Bean
scope:
依赖注入
构造方法 : 按照,索引,名称,类型注入
set方法注入: 必须提供set方法
<property name="username" >
p名称空间注入
1) 添加p名称空间
2) p:username=""
赋值
value: 赋值简单类型
ref:赋值pojo类型
注入集合属性: list ,set ,array
map properties