目录
Ioc
耦合
模块间关联度的度量,耦合度越低越好,尽量要做到“高内聚,低耦合”
耦合的分类
- 内容耦合
- 公共耦合
- 外部耦合
- 控制耦合
- 标记耦合
- 数据耦合
- 非直接耦合
解耦
核心思想
工厂模式:所有模块不直接注入依赖,而是通过工程的方法获得依赖,当需要改动时就只需改动工厂方法,而不需要更改每一个模块,也就是每个模块只负责“拿”对象,不负责“造”对象
IoC的定义
原来获取对象时用new关键字,是主动的,当我们需要更改实现类时,就需要重新改每个模块中new后的实现类
工厂模式,模块只需要和工厂“拿”实现类,比如使用工厂的getXXX方法,时被动的,创建对象交给了Spring的工厂,要更改实现类时,只需要更改工厂的方法就行
快速入门
准备工作
导入jar包
<!-- spring 核⼼依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
创建Spring Config xml文件
文件名任意,放在类路径(resource)下
编写Spring Config 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 http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
添加一个普通的引用类对象
默认单例模式
<?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">
<!--工厂可通过id找到这个对象-->
<bean id="u1" class="com.zzxx.domain.User" />
</beans>
多例模式
<!--每次取对象时,拿到的都是一个新对象-->
<bean id="u1" class="com.zzxx.domain.User" scope="prototype"/>
自定义一个工厂
当工厂的方法是静态方法时,不需要创建工厂对象
<!--MyFactory1.getUser方法是静态方法,调用该方法不需要创建MyFactory1对象-->
<bean id="myfactory1" class="com.zzxx.factorys.MyFactory1" factory-method="getUser"/>
当工厂的方法不是静态方法时,需要创建工厂对象
<!--当MyFactory2.getUser方法不是静态方法时,需要先创建一个MyFactory2类,再调用方法-->
<bean id="mf2" class="com.zzxx.factorys.MyFactory2"/><!--可以放在下面标签的后面-->
<bean id="myfactory2" factory-bean="mf2" factory-method="getUser" />
调用构造器创建对象
在<bean>标签内加<constructor-arg>标签,标签内各参数含义如下
- index:代表这是构造器参数列表内第几个参数,从0开始
- name:代表这个参数在构造器的参数列表中的名字
- value:代表这个参数的值(只能是基本数据类型或String)
- ref:代表这个参数的值(代表某个对象的引用,需要在配置文件中创建这个对象,该属性与value属性冲突)
- type:代表这个参数的类型(全限定类名)
<bean id="u1" class="com.zzxx.domain.User"/>
<bean id="p1" class="com.zzxx.domain.Person">
<constructor-arg index="1" name="name" value="张三" type="java.lang.String"/>
<constructor-arg index="2" name="age" value="18" type="int"/>
<!--ref引用的是上面定义好的user对象-->
<constructor-arg index="0" name="user" ref="u1" type="com.zzxx.domain.User"/>
</bean>
<bean id="p2" class="com.zzxx.domain.Person">
<property name="user" ref="u1"/>
<property name="name" value="张三"/>
<property name="age" value="18"/>
</bean>
注入集合属性
当类中存在集合属性,需要在xml文件中定义
list、set、数组的注入方式相同,只是标签名不同
<bean id="person" class="com.zzxx.domain.Person">
<property name="myArr"><!--name是这个集合属性在类中的名字-->
<array><!--set、list集合只需要将这里改成对应标签就行-->
<value>1</value>
<value>2</value>
</array>
</property>
<property name="myList" value="10"/><!--如果集合中只有一个值,可以直接在value属性定义-->
</bean>
map的注入方式
<property name="myMap">
<map>
<entry key="name" value="张三"/>
<entry key-ref="u1" value-ref="u1"/><!--键和值都可以使用引用-->
<entry key="age">
<value>18</value>
</entry>
</map>
</property>
properties的注入方式
<property name="myProp">
<props>
<prop key="name">张三</prop><!--注意key和value的位置-->
</props>
</property>
引用其他xml文件中的对象
<import resource="beans.xml"/>
获取工厂内的对象
创建工厂对象
ClassPathXmlApplicationContext对象
- 该工厂采用预加载模式,在读取配置文件后马上创建对象(当对象为多例模式时则对该对象懒加载),耗空间省时间
// ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
<!--实现类中自定义了一个close方法,ApplicationContext 无法使用close方法-->
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
XmlBeanFactory对象
- 该工厂采用懒加载模式,在调用getBran方法获取对象时才创建对象,耗时间省空间(现在不常用)
<!--注意构造器要传入一个Resource对象-->
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beans.xml"));
得到需要的对象
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
User u1 = (User) ac.getBean("u1");
User u2 = (User) ac.getBean("u1");//单例模式时,这里两个对象是同一个引用
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beans.xml"));
Object u1 = bf.getBean("u1");
Object u2 = bf.getBean("u1");//
注解创建对象
使用注解+xml的形式
导入jar包
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
编写Spring Config 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"
xmlns:context="http://www.springframework.org/schema/context"<!--注意这里增加了-->
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com"/><!--扫描包内所有注解-->
</beans>
总结
要尽量做到高内聚、低耦合
工厂创建对象时可以选择对象是否是单例模式
两种工厂用法相同,但是创建对象的时间不同,BeanFactory是IoC的核心,是所有工厂的底层