什么是Spring
spring是一个轻量级的Java 开源框架,Spring框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应
用程序开发提供集成的框架。
Spring框架中的所有组件模块都依赖于Spring提供的俩个基础功能:是控制反转( IOC )和面向切面编程( AOP )。
Spring优势
1.容器性质,方便解耦,简化开发(核心)
Spring提供的 IOC 容器,可以将对象间的依赖关系交由Spring容器进行控制,避免硬编码所造成的过度程序耦合。
2.AOP编程的支持(核心)
通过Spring的 AOP 功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
3.声明式事务的支持
通过声明式方式灵活的进行事务的管理,提高开发效率和质量
4.集成各种优秀框架
Spring不仅不排除其他各种优秀的框架,同时对这些框架(Mybatis、Quartz等)提供了很好的支持
5.降低JavaEE API的使用难度
Spring对JavaEE API 进行了封装,使得这些API降低了使用难度
IOC
IOC (Inverse of Control) 控制反转,将对象的创建以及对象依赖关系反转给Spring 容器,程序本身不进行维护
准备
我们需要导入一些我们我们所需要的jar包
这些我们都可以在Spring官网上找到
首先我们创建一个pojo类,由于使用了Lombok中的Data注解,该类编译后,会自动生成对应的GET/SET方法以及toString等方法:
public class Husband{
private int id;
private String name;
private double salary;
}
在src下面,创建配置文件,名字为: applicationContext.xml
并添加头部信息
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
<bean name="h1" class="com.briup.ioc.Husband"></bean>
<bean name="husband" class="com.briup.ioc.Husband"/>
<bean name="b1,b2,b3" class="com.briup.ioc.Husband"/>
<bean class="com.briup.ioc.Husband"/>
<bean class="com.briup.ioc.Husband"/></bean>
这里使用了name属性,也可以使用id
id: 一个bean的唯一标识 , 命名格式必须符合XML ID属性的命名规范
name: 可以用特殊字符,并且一个bean可以用多个名称,例如 name=“bean1,bean2,bean3”
如果没有id,则name的第一个名称默认是id
如果 一个 bean 标签未指定 id、name 属性,则 spring容器会给其一个默认的id,值为其类全名
如果有多个bean标签未指定 id、name 属性,但是class相同,则spring容器会按照其出现的次序,
分别给其指定 id 值为 “类全名#1”, “类全名#2”
并进行测试
public class SpringIoCTest {
public static void main(String[] args) {
// 1.解析配置文件,创建容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.根据配置的Id值,从容器中获取对象
Husband hunsband = (Husband) ac.getBean("husband");
System.out.println(hunsband); } }
得到的结果是
我们也可以通过其他的方式来获取对象
其中#1代表第一个
BeanFactory 和 ApplicationContext 的区别:
1.BeanFactory是Spring容器的顶层接口,ApplicationContext是其子接口
2.ApplicationContext接口,它由BeanFactory接口派生而来,包含BeanFactory的所有功能
3.BeanFactory 创建容器时不会创建对象,当从容器里面获取对象时才会创建
4.ApplicationContext 创建容器时就会创建对象
除此之外,我们也可以通过工厂来获取对象
/*
*
* 产出husband对象的工厂类*/
public class HusbandStaticFactory {
//静态方法获得husband
public static Husband getInstance() {
return new Husband();
}
}
然后我们在applicationContext.xml中配置工厂信息
<!--
实例工厂获得对象
实例工厂需要产生对象才能调用实例方法
所以需要配置两个bean
一个是工厂的bean,一个是产品的bean
factory-bean配置实例工厂的唯一标识
factory-method 配置实例工厂中获得产品的实例方法
-->
<bean id="factory" class="com.briup.ioc.HusbandFactory"/>
<bean id="hf" factory-bean="factory" factory-method="getInstance"/>
DI
如果一个对象的初始化需要依赖一些属性值或者其他对象,那么DI就可以帮我们来完成对象初始化时候属性的依赖注入工作。
set方法注入
构造器注入
<!--
构造器方式注入
三种方式
name 构造器参数名字
index 构造器参数下标从0开始
type 构造器参数类型,如果有相同类型,按顺序填充
注入值使用value
注入bean对象使用 ref
-->
<bean id="husband22" class="com.briup.ioc.Husband">
<constructor-arg name="id" value="1003"></constructor-arg>
<constructor-arg name="name" value="bom"></constructor-arg>
<constructor-arg name="salary" value="5000"></constructor-arg>
<constructor-arg name="date" ref="date"></constructor-arg>
<constructor-arg name="abc" value="abc"></constructor-arg>
</bean>
<bean id="husband23" class="com.briup.ioc.Husband">
<constructor-arg index="0" value="1003"></constructor-arg>
<constructor-arg index="1" value="bom"></constructor-arg>
<constructor-arg index="2" value="5000"></constructor-arg>
<constructor-arg index="3" ref="date"></constructor-arg>
<constructor-arg index="4" value="abc"></constructor-arg>
</bean>
<bean id="husband24" class="com.briup.ioc.Husband">
<constructor-arg type="int" value="1003"></constructor-arg>
<constructor-arg type="String" value="abc"></constructor-arg>
<constructor-arg type="String" value="bom"></constructor-arg>
<constructor-arg type="double" value="5000"></constructor-arg>
<constructor-arg type="java.util.Date" ref="date"></constructor-arg>
</bean>
命名空间的注入
首先要在xml文件中添加p:
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<!--
使用命名空间注入
p和c
本质上还是set方式和构造器方式注入,是一种简写
p properties
c constructor
-->
<bean id="husband31"
class="com.briup.ioc.Husband"
p:id="1004" p:name="lilith" p:salary="1000" p:date-ref="date" p:abc="测试p">
</bean>
<bean id="husband32"
class="com.briup.ioc.Husband"
c:id="1004" c:name="lilith" c:salary="1000" c:date-ref="date" c:abc="测试c">
</bean>
<bean id="husband33"
class="com.briup.ioc.Husband"
c:_0="1004" c:_1="lilith" c:_2="1000" c:_3-ref="date" c:_4="测试c_c">
</bean>
集合属性的注入
首先我们建立一个集合
public class Entity {
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String, String> myMap;
private Properties myProp;
private Map<Integer,Husband> myTestMap;
}
<!--
集合属性的注入
array
list
set
map
prop
-->
<bean id="entity" class="com.briup.ioc.Entity">
<!-- 注入数组 -->
<property name="myStrs">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<!-- 注入List -->
<property name="myList">
<list>
<value>DDD</value>
<value>EEE</value>
<value>FFF</value>
</list>
</property>
<!-- 注入Set -->
<property name="mySet">
<set>
<value>GGG</value>
<value>KKK</value>
<value>LLL</value>
</set>
</property>
<!-- 注入myMap -->
<property name="myMap">
<map>
<!-- 俩种形式都可以注入 -->
<entry key="name" value="tom"></entry>
<entry key="age">
<value>20</value>
</entry>
</map>
</property>
<!-- 注入Properties -->
<property name="myProp">
<props>
<prop key="username">root</prop>
<prop key="password">754750</prop>
</props>
</property>
<!-- 注入myMap -->
<property name="myTestMap">
<map>
<!-- 俩种形式都可以注入 -->
<entry key="name" value="tom"></entry>
<entry key="age">
<value>20</value>
</entry>
</map>
</property>
</bean>
值用value,对象则用ref