Spring是一个
轻量级的控制反转和面向切面的容器
框架,用来解决企业项目开发的复杂问题-解耦
IOC(Inverse of Control)
,把创建对象的工作交由Spring完成,Spring在创建对象的时候同时可以完成对象属性赋值(DI)AOP(Aspect Oriented Programming)
面向切面编程,可以在不改变原有业务逻辑的情况下实现对业务的增强官网
Spring容器组件,用于完成实例的创建和管理
Spring AOP组件,实现面向切面编程
Spring web组件实际指的是SpringMVC框架,实现web项目的实际控制
Spring的单元测试组件,提供了Spring环境下的单元测试支持
Spring IOC容器组件,可以完成对象的创建、对象属性赋值、对象管理
Spring框架部署(IOC)
创建Maven工程
context
(传递依赖core beans,aop,expression的jar包) <dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.19.RELEASEversion>
dependency>
dependencies>
通过配置文件告诉
Spring容器创建什么对象,给对象属性赋什么值
applicationContext.xml
的文件,
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="stuAge" value="21"/>
<property name="stuNum" value="10001"/>
<property name="stuName" value="李斯"/>
<property name="enterenceTime" ref="date"/>
bean>
<bean id="date" class="java.util.Date"/>
beans>
package com.qfedu.ioc.bean;
import java.util.Date;
/**
* @author Helen
* @version 1.0
* @createTime 2022/1/5 7:20
* @Description
*/
public class Student {
private String stuNum;
private String stuName;
private int stuAge;
/**入学时间*/
private Date enterenceTime;
public String getStuNum() {
return stuNum;
}
public void setStuNum(String stuNum) {
this.stuNum = stuNum;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
public Date getEnterenceTime() {
return enterenceTime;
}
public void setEnterenceTime(Date enterenceTime) {
this.enterenceTime = enterenceTime;
}
@Override
public String toString() {
return "Student{" +
"stuNum='" + stuNum + '\'' +
", stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
", enterenceTime=" + enterenceTime +
'}';
}
}
package com.qfedu.ioc.test;
import com.qfedu.ioc.bean.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Helen
* @version 1.0
* @createTime 2022/1/5 7:34
* @Description
*/
public class Test {
public static void main(String[] args) {
/**通过Spring容器创建Student对象*/
/**初始化Spring容器,加载Spring配置文件*/
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
/**通过Spring容器获取Student对象*/
Student object=context.getBean("stu", Student.class);
System.out.println(object);
}
}
当我们需要通过Spring对象工厂创建某个类的对象时候,需要将这个交给Spring管理-- 通过bean标签配置
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="stuAge" value="21"/>
<property name="stuNum" value="10001"/>
<property name="stuName" value="李斯"/>
<property name="enterenceTime" ref="date"/>
bean>
通过Spring容器给创建的对象属性赋值
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="stuAge" value="21"/>
<property name="stuNum" value="10001"/>
<property name="stuName" value="李斯"/>
<property name="enterenceTime" ref="date"/>
bean>
依赖注入三种方式
Spring容器加载配置文件之后,通过反射创建类的对象,并给属性赋值;Spring容器通过反射实现属性注入方式
- set方法注入
构造器注入
接口注入(不常用)
package com.qfedu.ioc.test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author Helen
* @version 1.0
* @createTime 2022/1/5 19:45
* @Description
*/
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> c =Class.forName("com.qfedu.ioc.bean.Student");
/**通过反射创建对象*/
Object obj=c.newInstance();
System.out.println(obj);
/**通过反射获取类中的属性*/
Field[]fields=c.getDeclaredFields();
for (Field field:fields){
String fieldName = field.getName();
String setMethodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
System.out.println(fieldName+"--------------------"+setMethodName);
if("stuNum".equals(fieldName)){
Method setMethod = c.getDeclaredMethod(setMethodName,field.getType());
setMethod.invoke(obj,"10001");
}
}
System.out.println(obj);
}
}
在bean标签中通过配置
property
标签给属性赋值,实际上就是通过反射掉用set方法完成属性的注入
简单类型及字符串
直接通过property 标签的value属性赋值
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="stuAge" value="21"/>
<property name="stuNum" value="10001"/>
<property name="stuName" value="李斯"/>
bean>
日期类型
property
标签中同ref
引用Spring容器中的一个对象 <bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="enterenceTime" ref="date"/>
bean>
<bean id="date" class="java.util.Date">
<property name="year" value="2021"/>
<property name="month" value="1"/>
<property name="date" value="6"/>
bean>
property
中添加子标签bean
来指定对象<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="enterenceTime">
<bean class="java.util.Date"/>
property>
bean>
自定义对象类型
property
标签中同ref
引用Spring容器中的一个对象 <bean class="com.qfedu.ioc.bean.Book" id="book">
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="32.4f"/>
bean>
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="book" ref="book"/>
bean>
property
中添加子标签bean
来指定对象 <bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="book">
<bean class="com.qfedu.ioc.bean.Book">
<property name="name" value="1"/>
<property name="price" value="32.4f"/>
bean>
property>
bean>
集合类型
List中的元素是字符串或者简单类型的封装类 <property name="hobbies" value="旅游,美食"/>
ListList中的元素是对象类型
<property name="hobbies">
<list>
<value>打羽毛球value>
<value>打篮球value>
list>
property>
<property name="books">
<list>
<bean class="com.qfedu.ioc.bean.Book"/>
<bean class="com.qfedu.ioc.bean.Book"/>
list>
property>
<property name="books">
<list>
<ref bean="book"/>
list>
property>
<property name="sets">
<set>
<value>美食value>
<value>旅游value>
set>
property>
<property name="map">
<map>
<entry key="英语" value="87"/>
<entry key="数学" value="96"/>
map>
property>
<property name="properties">
<props>
<prop key="username">rootprop>
<prop key="password">123456prop>
props>
property>
package com.qfedu.ioc.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.*;
/**
* @author Helen
* @version 1.0
* @createTime 2022/1/5 7:20
* @Description
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private String stuNum;
private String stuName;
private int stuAge;
/**入学时间*/
private Date enterenceTime;
private Book book;
private List<String>hobbies;
private Set<String>sets;
private Map<String,Object>map;
private Properties properties;
}
Spring配置文件
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.qfedu.ioc.bean.Book" id="book">
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="32.4f"/>
bean>
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<property name="stuAge" value="21"/>
<property name="stuNum" value="10001"/>
<property name="stuName" value="李斯"/>
<property name="enterenceTime">
<bean class="java.util.Date"/>
property>
<property name="book">
<bean class="com.qfedu.ioc.bean.Book">
<property name="name" value="1"/>
<property name="price" value="32.4f"/>
bean>
property>
<property name="hobbies" value="旅游,美食"/>
<property name="sets">
<set>
<value>美食value>
<value>旅游value>
set>
property>
<property name="map">
<map>
<entry key="英语" value="87"/>
<entry key="数学" value="96"/>
map>
property>
<property name="properties">
<props>
<prop key="username">rootprop>
<prop key="password">123456prop>
props>
property>
bean>
beans>
测试
package com.qfedu.ioc.test;
import com.qfedu.ioc.bean.Student;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Helen
* @version 1.0
* @createTime 2022/1/5 7:34
* @Description
*/
public class Test {
public static void main(String[] args) {
/**通过Spring容器创建Student对象*/
/**初始化Spring容器,加载Spring配置文件*/
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
/**通过Spring容器获取Student对象*/
Student object=context.getBean("stu", Student.class);
System.out.println(object);
}
}
结果
Student(stuNum=10001, stuName=李斯, stuAge=21, enterenceTime=Thu Jan 06 20:03:06 CST 2022, book=Book(name=1, price=32.4), hobbies=[旅游,美食], sets=[美食, 旅游], map={英语=87, 数学=96}, properties={password=123456, username=root})
简答类型、字符串、对象、集合类型属性
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="book" class="com.qfedu.ioc.bean.Book">
<property name="price" value="32.5f"/>
<property name="name" value="红楼梦"/>
bean>
<bean class="java.util.Date" id="date"/>
<bean id="stu" class="com.qfedu.ioc.bean.Student">
<constructor-arg name="stuName" value="小明"/>
<constructor-arg name="enterenceTime" ref="date"/>
<constructor-arg name="book" ref="book"/>
<constructor-arg name="stuAge" value="21"/>
<constructor-arg name="stuNum" value="10001"/>
<constructor-arg name="weight" value="22.0"/>
<constructor-arg name="hobbies">
<list>
<value>旅游value>
<value>美食value>
list>
constructor-arg>
<constructor-arg name="sets">
<set>
<value>111value>
<value>222value>
set>
constructor-arg>
<constructor-arg name="map">
<map>
<entry key="英语" value="27"/>
<entry key="数学" value="28"/>
map>
constructor-arg>
<constructor-arg name="properties">
<props>
<prop key="username">rootprop>
<prop key="password">123456prop>
props>
constructor-arg>
bean>
beans>
在
bean
标签可以通过scope属性指定对象的作用域
scope="singleton"
表示当前bean是单例模式(默认饿汉模式,Spring容器初始化阶段就会完成此对象的创建;当在bean标签中设置lay-init="true"
变为懒汉模式)
scope="prototype"
表示当前bean为非单例模式,每次通过Spring容器获取此bean的对象时都会创建一个新的对象
<bean id="stu" class="com.qfedu.ioc.bean.Student" scope="singleton" lazy-init="true">
bean>
<bean id="stu" class="com.qfedu.ioc.bean.Student" scope="prototype">
bean>
package com.qfedu.ioc.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.*;
/**
* @author Helen
* @version 1.0
* @createTime 2022/1/5 7:20
* @Description
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private String stuNum;
private String stuName;
private int stuAge;
private double weight;
/**入学时间*/
private Date enterenceTime;
private Book book;
private List<String>hobbies;
private Set<String>sets;
private Map<String,Object>map;
private Properties properties;
/**
* 初始化方式:在创建当前类对象时调用的方法,进行资源的准备
*/
public void init(){
System.out.println("-------init");
this.stuName="李斯";
this.stuAge=21;
}
/**
* 销毁方法:在Spring容器销毁对象时调用此方法,进行一些资源回收性的操作
*/
public void destroy(){
System.out.println("--------destroy");
this.stuName="";
this.stuAge=0;
}
}
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="stu" class="com.qfedu.ioc.bean.Student" scope="prototype" init-method="init" destroy-method="destroy">
bean>
beans>
自动装配:Spring在实例化当前bean的时候从Spring容器中找到匹配的实例赋值给当前bean的属性
自动装配策略有两种:
byName
byType
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="book" class="com.qfedu.ioc.bean.Book">
<property name="name" value="红楼梦"/>
<property name="price" value="32.5f"/>
bean>
<bean id="stu" class="com.qfedu.ioc.bean.Student" autowire="byName">
bean>
beans>
SpringIoc的使用,需要我们通过XML将类声明给Spring容器进行管理,从而通过Spring工厂完成对象的创建及属性值的注入
Spring除了提供基于XML的配置方式,同时提供了基于注解的配置,直接在实体类中添加注解声明给Spring容器管理,以简化开发步骤。
在applicationContext.xml声明Spring的扫描范围
,以达到Spring初始化时扫描带有注解的实体类并完成初始化工作。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.qfedu.ioc.bean"/>
beans>
@Component(value="stu")
value属性用于指定当前bean的id,相当于bean标签的id属性;value属性也可以省略,如果省略当前类的id默认为类名首字母小写@Service @Controller @Repository
这三个注解也可以将类声明给Spring管理,主要时语义上的区别 @Autowired
public void setClazz(@Qualifier("c1") Clazz clazz) {
this.clazz = clazz;
}