Spring框架概述
Spring框架概述
- Spring是轻量级的开源的JAVAEE框架
- Spring可以解决企业应用开发的复杂性
- Spring有两个核心部分:IOC和Aop
- IOC:控制反转,把创建对象的过程交个Spring进行管理
- Aop:面向切面,不修改源代码进行功能增强
- Spring特点
- 方便解耦,简化开发
- Aop编程支持
- 方便程序测试
- 方便和其他框架进行整合
- 方便进行事务操作
- 降低API的使用难度
IOC容器
- IOC底层原理
- IOC接口(BeanFactory)
- IOC操作Bean管理(基于XML)
- IOC操作Bean管理(基于注解)
IOC概念和原理
什么是IOC
控制反转,把对象创建和对象之间调用过程,交给Spring进行管理
使用IOC目的:为了耦合度降低
IOC底层原理
xml解析,工厂模式,反射
IOC接口
-
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
-
Spring提供IOC容器实现两种方式:(两个接口)
- BeanFactory:
- IOC容器基本实现方式,是spring内部使用接口,不提供开发人员进行使用
- 加载配置文件不会创建对象,在获取对象才去创建对象
- ApplicationContext:
- BeanFactory接口的子接口,提供更多更强大的功能,一般是由开发人员进行使用
- 加载配置文件时候就会把配置文件对象进行创建
使用ApplicationContext把加载过程交给启动服务器,不要留给运行中。
- BeanFactory:
-
ApplicationContext接口有实现类
盘路径 类路径
IOC操作Bean管理
- 什么是Bean管理
- Spring创建对象
- Spring注入属性
- Bean管理操作有两种方式
- 基于xml配置文件方式实现
- 基于注解方式实现
IOC操作Bean管理(xml)
基于xml方式创建对象
- 在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
- 在bean标签有很多属性,常用属性:
- id属性:唯一标识
- class属性:类全路径
- 创建对象时候,默认是执行无参构造
基于xml方式注入属性
DI:依赖注入,注入属性
使用set方法注入
创建类,定义属性和对应set方法
package com.yuhang.spring5;
public class Book {
private String bname;
private String bauthor;
public void setBname(String bname) {
this.bname = bname;
}
public void setBauthor(String bauthor) {
this.bauthor = bauthor;
}
public void testDemo(){
System.out.println(bname+"::"+bauthor);
}
// public static void main(String[] args){
// Book book = new Book();
// book.setBname("abc");
// }
}
在Spring配置文件配置对象创建,配置属性注入
<!--set方法注入属性-->
<bean id="book" class="com.yuhang.spring5.Book">
<!--使用property完成属性注入
name 类里面属性名称
value 向属性注入的名称
-->
<property name="bname" value="易经经"></property>
<property name="bauthor" value="六脉神剑"></property>
</bean>
使用有参构造注入
创建类,定义属性,创建属性对应有参数构造方法
package com.yuhang.spring5;
/**
* 使用有参构造注入
*/
public class Orders {
//属性
private String oname;
private String address;
//有参构造
public Orders(String oname, String address) {
this.oname = oname;
this.address = address;
}
}
在Spring配置文件中进行配置
<bean id="orders" class="com.yuhang.spring5.Orders">
<constructor-arg name="oname" value="pc"></constructor-arg>
<constructor-arg name="address" value="china"></constructor-arg>
</bean>
p名称空间注入
使用p名称空间注入,可以简化基于xml配置方式
第一步添加p名称空间在配置文件
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
第二步 进行属性注入,在bean标签里进行操作
<bean id="book" class="com.yuhang.spring5.Book" p:bname="九阳" p:bauthor="无名">
</bean>
IOC操作Bean管理(xml注入其他类型属性)
1.字面量
1.null值
<property name="bname">
<null/>
</property>
2.属性包含特殊符号
<!--
1.转义
2.写入CDATA
-->
<property name="bname">
<value><![CDATA[<<南京>>]]></value>
</property>
2.注入属性 外部bean
1.创建两个类service类和dao类
2.在service调用dao里的方法
3.在Spring配置文件中配置
package com.yuhang.spring5.service;
import com.yuhang.spring5.dao.UserDao;
public class UserService {
//创建UserDao类型属性,生成set方法
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add(){
System.out.println("service add ");
userDao.update();
//原始方式
//创建UserDao对象
// UserDao userDao = new UserDaoImpl();
// userDao.update();
}
}
<!--service和dao对象创建-->
<bean id="userService" class="com.yuhang.spring5.service.UserService">
<!-- 注入userDao对象
name属性:类里面属性名称
ref属性:创建userDao对象bean标签id值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="com.yuhang.spring5.dao.UserDaoImpl"></bean>
3.注入属性 内部bean和级联赋值
1.一对多关系:部门一,员工多
2.在实体类之间表示一对多关系
//部门类
public class Dept {
private String dname;
public void setDname(String dname) {
this.dname = dname;
}
}
//员工类
public class Emp {
private String ename;
private String gender;
//员工属于某一个部门
public Dept dept;
public void setDept(Dept dept) {
this.dept = dept;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setEname(String ename) {
this.ename = ename;
}
}
3.在Spring配置文件中配置
<!--内部bean-->
<bean id="emp" class="com.yuhang.spring5.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="lucy"></property>
<property name="gender" value="女"></property>
<property name="dept">
<bean id="dept" class="com.yuhang.spring5.bean.Dept">
<property name="dname" value="人事部"></property>
</bean>
</property>
</bean>
4.注入属性,级联赋值
<!--级联赋值-->
<bean id="emp" class="com.yuhang.spring5.bean.Emp">
<!--设置两个普通属性-->
<property name="ename" value="lucy"></property>
<property name="gender" value="女"></property>
<!---->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.yuhang.spring5.bean.Dept">
<property name="dname" value="人事部"></property>
</bean>
第二种级联直接使用,但要生成对应get方法。
<property name="dept.dname" value="人事部"></property>
IOC操作Bean管理(xml注入集合)
1.数组
2.list
3.map
4.set
设置对象类型值
公共提取
IOC操作Bean管理(FactoryBean)
视频:bean工厂
Spring有两种类型的bean,一种普通,一种工厂
- 普通bean:在配置文件中定义bean类型就是返回类型
- 工厂bean:在配置文件定义bean类型可以和返回类型不一样
- 第一步:创建类,让这个类作为工厂bean,实现接口
- 第二步:实现接口方法,定义返回bean类型
IOC操作Bean管理(bean作用域)
- 在spring里面,设置创建bean实例是单实例还是多实例
- 在spring里面,默认情况下bean是单实例对象
- 地址相同,默认单实例对象
- 如何设置单实例和多实例
- 在spring配置文件里有scope属性用于设置
- scope属性值
- 第一个值,默认值singleton,表示是单实例对象
- 第二个值,prototype,表示是多实例对象
- 地址不同,多实例对象
- request,session
- singleton和prototype区别
- singleton,表示是单实例对象,prototype,表示是多实例对象
- 设置singleton,加载spring配置文件时就会创建单实例对象。设置prototype,不是在加载时创建,而是在调用getBean方法的时候创建多实例对象。
IOC操作Bean管理(bean生命周期)
-
生命周期
- 从对象创建到对象销毁的过程
-
bean生命周期
- 通过构造器创建bean实例(无参构造)
- 为bean的属性设置值和对其他bean的引用(调用set)
- 调用bean的初始化方法(需要配置)
- bean可以使用(对象获取成功)
- 当容器关闭时候,调用bean销毁的方法(需要配置销毁方法)
-
演示bean生命周期
-
package com.yuhang.spring5.bean; public class Zhou { private String bzhou; public Zhou() { System.out.println("1.通过构造器创建bean实例(无参构造)"); } public void setBzhou(String bzhou) { this.bzhou = bzhou; System.out.println("2.为bean的属性设置值和对其他bean的引用(调用set)"); } public void init() { System.out.println("3.调用bean的初始化方法(需要配置)"); } public void end() { System.out.println("5.当容器关闭时候,调用bean销毁的方法(需要配置销毁方法)"); } @Override public String toString() { return "Zhou{" + "bzhou='" + bzhou + '\'' + '}'; } }
-
<?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"> <bean id="zhou" class="com.yuhang.spring5.bean.Zhou" init-method="init" destroy-method="end"> <property name="bzhou" value="生命周期"></property> </bean> </beans>
-
@Test public void testZhou(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Zhou zhou = context.getBean("zhou", Zhou.class); System.out.println("4.bean可以使用(对象获取成功)" + zhou); //手动 context.close(); }
-
-
bean的后置处理器
- 通过构造器创建bean实例(无参构造)
- 为bean的属性设置值和对其他bean的引用(调用set)
- 把bean的实例传递bean后置处理器的方法
- 调用bean的初始化方法(需要配置)
- 把bean的实例传递bean后置处理器的方法
- bean可以使用(对象获取成功)
- 当容器关闭时候,调用bean销毁的方法(需要配置销毁方法)
-
演示添加后置处理器效果
-
package com.yuhang.spring5.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class Mybean implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("前"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("后"); return bean; } }
-
package com.yuhang.spring5.bean; //员工类 public class Emp { private String ename; private String gender; //员工属于某一个部门 public Dept dept; public void setDept(Dept dept) { this.dept = dept; } public void setGender(String gender) { this.gender = gender; } public void setEname(String ename) { this.ename = ename; } public void add(){ System.out.println("内部bean"); System.out.println(ename+gender+dept); } @Override public String toString() { return "Emp{" + "ename='" + ename + '\'' + ", gender='" + gender + '\'' + ", dept=" + dept + '}'; } }
-
<bean id="zhou" class="com.yuhang.spring5.bean.Zhou" init-method="init" destroy-method="end"> <property name="bzhou" value="生命周期"></property> </bean> <bean id="emp" class="com.yuhang.spring5.bean.Emp"> <property name="ename" value="后置处理器"></property> </bean> <!--后置处理器--> <bean id="mybean" class="com.yuhang.spring5.bean.Mybean"></bean>
-
@Test public void testZhou(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Zhou zhou = context.getBean("zhou", Zhou.class); System.out.println("4.bean可以使用(对象获取成功)" + zhou); //手动 context.close(); }
-