使用Spring的容器对对象进行管理,而不是用户根据需求创建对象,这一过程称为控制反转。
创建一个Maven工程,模拟表现层、业务层、持久层。
为了导入spring框架,进行pom文件配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ethan</groupId>
<artifactId>day01_eesy_03spring</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
然后在resources下创建bean.xml,指明对象的id,要创建对象的类:
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">
<!--把对象的创建交给spring来管理-->
<bean id = "accountService" class = "com.ethan.service.impl.AccountServiceImpl"></bean>
<bean id = "accountDao" class = "com.ethan.dao.impl.AccountDaoImpl"></bean>
</beans>
Client
类实现如下:
package com.ethan.ui;
import com.ethan.dao.AccountDao;
import com.ethan.service.AccountService;
import com.ethan.service.impl.AccountServiceImpl;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/*
模拟一个表现层,用于调用业务层
*/
public class Client {
/*
获取Spring的IOC核心容器,并根据id获取对象
*/
public static void main(String[] args) {
//1.获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// ApplicationContext ac = new FileSystemXmlApplicationContext("D:\\work_space\\src\\main\\resources\\bean.xml");
//2.根据id获取Bean对象
AccountService as = (AccountService) ac.getBean("accountService");
AccountDao aDao = ac.getBean("accountDao", AccountDao.class); //两种方式
System.out.println(as);
System.out.println(aDao);
as.saveAccount();
//----------------------------------------------------
// Resource res = new ClassPathResource("bean.xml");
// BeanFactory factory = new XmlBeanFactory(res);
// AccountService as = (AccountService) factory.getBean("accountService"); //运行到这句时创建对象
// System.out.println(as);
}
}
ApplicationContext的三个常用实现类:
ClassPathXmlApplicationContext
:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。FileSystemXmlApplicationContext
:可以加载磁盘任意路径下的配置文件(必须有访问权限),相比而言,第一个更常用。AnnotationConfigApplicationContext
:它是用于读取注解创建容器的。
核心容器的两个接口引发出的问题:
ApplicationContext
:单例对象适用,实际开发中通常采用此接口。它在构建核心容器时,创建对象采取的策略是采用立即加载的方式,也就是说,只要一读取完配置文件,马上创建配置文件中配置的对象;BeanFactory
:多例对象适用。它在构建核心容器时,创建对象采用的策略是采用延迟加载的方式,也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
bean的生命周期
单例对象:
- 出生:当容器创建时出生。
- 存活:只要容器还在,对象一直存活。
- 死亡:容器销毁,对象消亡。
多例对象:
- 出生:当我们使用对象时Spring框架为我们创建。
- 存活:对象只要是在使用过程中就一直活着。
- 死亡:当对象长时间不用且没有别的对象引用时,由Java的垃圾回收器回收。
业务层:
package com.ethan.service.impl;
import com.ethan.service.AccountService;
/*
账户的业务层实现类
*/
public class AccountServiceImpl implements AccountService {
public AccountServiceImpl() {
System.out.println("对象创建了");
}
public void init() {
System.out.println("对象初始化了");
}
public void destroy() {
System.out.println("对象销毁了");
}
public void saveAccount() {
System.out.println("Service中的saveAccount方法执行了");
}
}
bean配置:
<!--bean的作用范围调整
bean标签scope属性:
作用:用于指定bean的作用范围
取值:常用singleton和prototype
singleton:单例(默认)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,他就是session
-->
<bean id = "accountService" class = "com.ethan.service.impl.AccountServiceImpl" scope="prototype" init-method="init" destroy-method="destroy"></bean>
package com.ethan.ui;
import com.ethan.service.AccountService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
模拟一个表现层,用于调用业务层
*/
public class Client {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //单例对象在这时创建
AccountService as = (AccountService) ac.getBean("accountService"); //多例对象在使用时创建
System.out.println(as);
as.saveAccount();
ac.close();
}
}