一.Spring IOC是什么
1.IOC简述
Ioc—Inversion of Control,即“控制反转”,是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。简言之,就是使用对象的时候不再“随用随new”,也不用new一个对象然后给它赋值,这些通过IOC容器都能由系统自动生成。
2.Spring IOC优点
- 轻量级 2. 依赖注入 3. 面向切面编程 4. 容器 5. 一站式
二.如何使用Spring IOC
- 搭建Spring 环境
1.引入4个所需jar包 spring-beans spring-context spring-core spring expression
2.配置文件,在target\classes\config目录下创建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>
2.作用域scope
1.singleton (默认属性)
Spring将Bean放入Spring IOC容器的缓存池中,并将Bean引用返回给调用者,spring
IOC继续对这些Bean进行后续的生命管理。BeanFactory只管理一个共享的实例。所有对这个特定 bean的实例请求,都导致返回这个唯一
bean实例的引用。
即每次拿到的对象都是引用的同一个地址的对象。当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。
2.prototype
Spring将Bean返回给调用者,调用者负责Bean后续生命的管理,Spring不再管理这些Bean的生命周期。
每次对这个bean的实例请求都会导致一个新的实例的创建。当用户需要不受其他用户对象影响的对象或有类似的需求时,这是一个较理想的解决办法。
即每次拿到的对象都是引用的不同地址的对象。相当于一个new的操作。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责
3.依赖注入
3.1.属性注入步骤
3.1.1.在目标类中声明属性并生成Set方法
3.1.2.在xml文件中进行配置
<bean id="apple" class="com.zzxtit.spring.ioc.dev.Apple" scope="prototype" name="weight" value="0.5KG"></bean>
<bean id="banana" class="com.zzxtit.spring.ioc.dev.Banana" name="weight" value="0.2KG"></bean>
3.1.3在Test类中使用
注:若属性值为引用类型,则value换成ref,引号的内容换为该引用类型在bean中注入时的id
public static void main(String[] args) {
Apple apple = (Apple) FruitFactory.getFruit("apple");
Orange orange = (Orange) FruitFactory.getFruit("orange");
System.out.println(orange + "============>" + apple);
}
3.2.构造器注入(通过构造方法注入)
spring 通过构造器注入,两种方式:
3.2.1、通过构造方法的参数的顺序,使用属性INDEX, 从0开始。使用方法同3.1.3
<bean id="constructorDi" class="com.zzxtit.spring.ioc.di.ConstructorDI">
<constructor-arg index="0" ref="apple">
</constructor-arg>
<constructor-arg index="1" value="张三">
</constructor-arg>
<constructor-arg index="2" value="19">
</constructor-arg>
</bean>
3.2.2、通过参数的类型确认使用的构造方法,使用属性ype, 如果基本数数据类型或者String类型,直接写类型名称,如果是自定义或者其他引用类型,需要全类名。使用方法同3.1.3。
<bean id="constructorDi" class="com.zzxtit.spring.ioc.di.ConstructorDI">
<constructor-arg type="java.lang.String" alue="realName李学霸">
</constructor-arg>
<constructor-arg type="java.lang.String" value="userName李学霸">
</constructor-arg>
<constructor-arg type="com.zzxtit.spring.ioc.di.Apple" ref="apple">
</constructor-arg>
<constructor-arg type="int" value="19">
</constructor-arg>
</bean>
4.注入集合(List Map Set properties)
4.1.在xml中将所需集合注入
<bean id="collectionDi"
class="com.zzxtit.spring.ioc.di.CollectionDI">
<property name="stuList">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="major">
<set>
<value>major1</value>
<value>major2</value>
<value>major3</value>
</set>
</property>
<property name="score" ref="scoreMap">
<map>
<entry key="stu1" value="70"></entry>
<entry key="stu2" value="79"></entry>
<entry key="stu3" value="76"></entry>
</map>
</property>
<property name="pro">
<props>
<prop key="mysql_url">jdbc:mysql://localhost:3306/test</prop>
<prop key="mysql_driver">com.jdbc.mysql.Driver</prop>
<props>
</property>
</bean>
4.2.在Test类中调用IOC容器创建CollectionDi对象
注:CollectionDi类重写toString方法便于结果显示,代码如下
@Override
public String toString() {
return "CollectionDI [stuList=" + stuList.getClass() + ", majorList=" + majorList.getClass() + ", score=" + score.getClass() + ", pro=" + pro
+ "]";
}
测试类中代码如下
public static void main(String[] args) {
ApplicationContext ioc = new ClassPathXmlApplicationContext("config/applicationContext-di.xml");
//参数为applicationContext-di.xml目录
CollectionDI collectionDi = ioc.getBean("collectionDi", CollectionDI.class);
System.out.println("============>" + collectionDi);
//因为重写了toString,所以打印结果是集合的内容
}
5 util标签,p命名空间,引入外部属性文件
5.1使用 util schema 里的集合标签定义独立的集合 Bean,可以被公用。
注:使用util标签时需引入:
1、命名空间:xmlns:util=“http://www.springframework.org/schema/util”
2、引入xsd文件:http://www.springframework.org/schema/util
https://www.springframework.org/schema/util/spring-util.xsd
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/util
https://www.springframework.org/schema/util/spring-util.xsd">
</beans>
声明如下
<util:map id="scoreMap">
<entry key="张" value="70"></entry>
<entry key="李" value="79"></entry>
<entry key="赵" value="76"></entry>
</util:map>
使用如下,在properties中用ref引用被声明的bean的id
<bean id="collectionDi"
class="com.zzxtit.spring.ioc.di.CollectionDI">
<property name="score" ref="scoreMap">
</property>
</bean>
5.2 p命名空间
Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过 <bean> 元素属性的方式配置 Bean 的属性
注:使用p命名空间需要引入命名空间:xmlns:p="http://www.springframework.org/schema/p"
xmlns:p="http://www.springframework.org/schema/p"
p标签的使用示例
<bean id="apple" class="com.springioc.Apple" p:color="红色" p:type="普通">
</bean>
<bean id="studentPtest" class="com.springioc.Student" p:teacher-ref="teacher">
</bean>
5.3引入外部属性文件
Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中. 可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量.
Spring还允许在属性文件中使用${propName},以实现属性之间的相互引用。在Spring2.5之后:可通过<context:property-placeholder>元素,在<beans>中添加context Schema定义。在配置文件中添加如下配置:<context:property-placeholder location="calsspath:db.properties">
1).创建属性文件:*.properties 文件内容为key=value的键值方式
eg:在config文件夹下新建一个db.properties文件,内容如下
mysql_url=jdbc:mysql://localhost:3306/test
mysql_driver=com.jdbc.mysql.Driver
2).在xml文件中用${ }引用该文件内容
<!-- 引入properties 配置文件 -->
<context:property-placeholder location="config/db.properties"/>
<bean id="collectionDi" class="com.springioc.CollectionDI">
<property name="pro">
<props>
<prop key="mysql_url">${mysql_url}</prop>
<prop key="mysql_driver">${mysql_driver}</prop>
</props>
</property>
</bean>
6.SPEL
1.SPEL简述
1.1.Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL
1.2.SpEL 为 bean 的属性进行动态赋值提供了便利
1.3.SpEL作用:
1).通过 bean 的 id 对 bean 进行引用
2).调用方法以及引用对象中的属性
3).计算表达式的值
4).正则表达式的匹配
2.引用 Bean、属性和方法
<bean id="stu" class="com.springioc.Student">
<property name="ci1" value="#{ci}">/property>
<property name="ci2" value="#{ci.toString}">/property>
<property name="ci3" value="#{ci.class}">/property>
</bean>
注:当value的值是一个方法时,其对应的property标签的name值"ci2"应该为一个属性跟被引用方法( toString() )返回值相同的bean注入的类(Student)中的变量。
7.自动装配
1).语法
<bean id="..." class=".." autowire="byType"/>
2).autowire属性取值如下:
byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。
Constructor:与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
8.在classpath自动扫描Bean组件(通过加注解的方式)
1.特定组件包括:
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Repository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件
注:对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称
2.@Autowired 注解自动装配具有兼容类型的单个 Bean属性
2.1.构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Autowired 注解
2.2默认情况下, 所有使用 @Autowired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Autowired 注解的 required 属性为 false
2.3默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 以指定注入 Bean 的名称
2.4@Autowired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.
2.5@Autowired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.
2.6@Autowired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值