耦合: 程序间的依赖关系
包括: 类之间的依赖,方法间的依赖
解耦: 降低程序间的依赖关系
实际开发中,应该做到,编译器不依赖,运行时才依赖
解耦的思想:
使用反射来创建对象,而避免使用new关键字
通过读取配置文件来获取要创建的对象的全限定类名
而学习Spring的目的就是为了将类与类之间的耦合性大大降低。即将对象的创建交给Spring来管理。
spring的管理细节
注意:第二种和第三种方式都可以用来得到jar包中某个方法返回的对象
示例:
<!--方式一 使用默认的构造函数创建 -->
<bean id="accountService" class="com.xatu.service.impl.AccountServiceImpl"></bean>
<!--方式二 使用普通工厂中的普通方法创建对象(使用某个类中的方法创建对象,并存入spring容器) -->
<bean id="instanceFactory" class="com.xatu.factory.InstanceFactory"></bean>
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
<!--方式三 使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)-此例中getAccountService()为静态方法->
<bean id="accountService" class="com.xatu.factory.staticFactory" factory-method="getAccountService"></bean>
bean标签的scope属性:
作用: 用于指定的bean的作用范围
取值:
单例对象: 预加载
出生:容器创建时
活着:容器在,则对象存活
死亡:容器不在,对象死亡
总结:单例对象的生命周期和容器的周期相同
多例对象: 懒加载
出生:当我们使用对象时,spring框架为我们创建
活着:对象只要是在使用过程中就一直活着
死亡:当对象长时间不用,且没有别的对象使用时,由Java的垃圾回收器回收
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
3.在resources目录下新建一个bean.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>
此时 环境搭建完成。
依赖注入即 Dependency Injection
IOC的作用:降低程序间的耦合度(依赖关系)
依赖关系的管理: 以后都交给spring来维护
在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护就称之为依赖注入
依赖注入
能注入的数据有三类:
1.基本类型和String类型
2.基本bean类型(在配置文件中或者注释配置过的bean)
3.复杂类型/集合类型
注入的方式:三种
1.使用构造函数提供
2.使用set方法提供
3.使用注释提供
方式一:构造函数注入
使用的标签: constructor-arg 标签出现在bean标签内
属性:
type:用于指定要输入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引位置从0开始
name:用于指定给构造函数中指定名称的参数赋值 (常用)
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据,它指的就是在spring的Ioc核心容器中出现过的bean对象
> 如Date类型 可以写成 <bean id="now" class="java.util.Date"></bean>
> 然后用<constructor-arg>便签赋值即可
> <constructor-arg name="date" ref="now"></constructor-arg>
优势: 在获取bean对象时,注入数据是必须操作,否则对象无法创建成功
弊端: 改变了bean对象的实例化方式,是我们才开发过程中,如果用不到这些数据,也必须提供
方式二:set方法注入 更常用
**使用的标签:**property 出现的位置:bean标签的内部
标签的属性:
**name:**用于指定注入时所调用的set方法名成 即对应的属性名
**value:**用于提供基本类型和String类型的数据
**ref:**用于指定其他的bean类型数据,它指的就是在spring的Ioc核心容器中出现过的bean对象
优势: 创建对象时没有明确的限制,可以直接使用某人后遭参数
弊端: 如果由某个成员必须有值,则获取对象是有可能set方法没有执行
3.复杂类型的注入
如数字 集合 Properties类型
用于给List结构集合注入的标签: list array set
用于给Map结构结合注入的标签: map props
举例如下:
<bean id="student" class="com.xatu.domain.Student">
<property name="name" value="小王"></property> //简单类型
<property name="date" ref="now"></property> //基本bean类型
<property name="myArr"> //复杂类型
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myList">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myset">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myMap">
<map>
<entry key="test1" value="name1"></entry>
<entry key="test2" value="name2"></entry>
<entry key="test3" value="name3"></entry>
</map>
</property>
<property name="mypros">
<props>
<prop key="test1">name1</prop>
<prop key="test2">name2</prop>
<prop key="test3">name3</prop>
</props>
</property>
</bean>
//接口 可以解耦
public interface People {
void play(String name,Date date);
}
Student.java
//实现类
public class Student implements People {
private String name;
private Date date;
private List myList;
private String[] myArr;
private Set myset;
private Map<String,String> myMap;
private Properties mypros;
public void setName(String name) {
this.name = name;
}
public void setDate(Date date) {
this.date = date;
}
public String getName() {
return name;
}
public Date getDate() {
return date;
}
public void setMyList(List myList) {
this.myList = myList;
}
public void setMyArr(String[] myArr) {
this.myArr = myArr;
}
public void setMyset(Set myset) {
this.myset = myset;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void setMypros(Properties mypros) {
this.mypros = mypros;
}
public void play(String name, Date date) {
System.out.println(name + "在" + date + "玩了游戏" );
}
public void test1(){
System.out.println("Array:" + Arrays.toString(myArr));
System.out.println("set:" + myset);
System.out.println("list:" + myList);
System.out.println("map:" + myMap);
System.out.println("pros:" + mypros);
}
}
testSpring.java
//测试类
public class testSpring {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
Student student = (Student) ac.getBean("student");
student.play(student.getName(),student.getDate());
student.test1();
}
}
bean.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">
<bean id="student" class="com.xatu.domain.Student">
<property name="name" value="小王"></property>
<property name="date" ref="now"></property>
<property name="myArr">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myList">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myset">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myMap">
<map>
<entry key="test1" value="name1"></entry>
<entry key="test2" value="name2"></entry>
<entry key="test3" value="name3"></entry>
</map>
</property>
<property name="mypros">
<props>
<prop key="test1">name1</prop>
<prop key="test2">name2</prop>
<prop key="test3">name3</prop>
</props>
</property>
</bean>
<bean id="now" class="java.util.Date"></bean>
</beans>