首先准备一些类来模拟三层架构
dao层 IAccountDao的实现类:AccountDaoImpl
package com.itheima.dao.impl; import com.itheima.dao.IAccountDao; /** * 账户的持久层实现类 */ public class AccountDaoImpl implements IAccountDao { public void saveAccount(){ System.out.println("保存了账户"); } }
service层 IAccountService 的实现类:AccountServiceImpl
package com.itheima.service.impl; import com.itheima.dao.IAccountDao; import com.itheima.dao.impl.AccountDaoImpl; import com.itheima.service.IAccountService; /** * 账户的业务层实现类 */ public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao = new AccountDaoImpl(); public AccountServiceImpl(){ System.out.println("无参构造函数——对象创建"); } public AccountServiceImpl(String a){ System.out.println(); } public void saveAccount(){ System.out.println("service 中的 saveAccount 被执行"); accountDao.saveAccount(); } }
ui层 client对象
package com.itheima.ui; import com.itheima.dao.IAccountDao; import com.itheima.service.IAccountService; import com.itheima.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获取对象 * AppliactionContext 的三个常用实现类: * ClassPathXmlApplicationContext: 可以加载类路径下的配置文件,要求配置文件必须在类路径下,否则无法加载 * FileSystemXmlApplicationContext: 可以加载磁盘任意路径下的配置文件,要求时必须有访问权限 * AnnotationConfigApplicationContext:读取注解创建容器 * * 核心容器的两个接口引发出的问题: * ApplicationContext:单例对象适用 * 它在构建核心容器时,创建对象采取的策略是采用立即加载方式。 * 也就是说,只要一读取完配置文件马上就创建配置文件配置的对象 * BeanFactory:多例对象适用 * 它在构建核心容器时,创建对象采取的策略是延迟加载的方式。 * 也就是说,什么时候根据id获取对象,什么时候才真正创建对象 * @param args */ public static void main(String[] args) { //1.获取核心容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");//更常见 //ApplicationContext ac = new FileSystemXmlApplicationContext("C:\Users\ASUS\IdeaProjects\day01__eesy_03sptring\src\main\resources\bean.xml"); //2.根据id获取bean对象(两种创建方式) IAccountService as = (IAccountService)ac.getBean("accountService");//马上创建对象 IAccountDao adao = ac.getBean("accountDao",IAccountDao.class); System.out.println(as); System.out.println(adao); as.saveAccount(); /* //--------BeanFactory----------- Resource resource = new ClassPathResource("bean.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); IAccountService as = (IAccountService) beanFactory.getBean("accountService"); System.out.println(as);//在此才创建对象 */ } }
重点:使用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来管理--> <!--spring 对 bean 的管理的细节 1.创建bean的三种方式 2.bean对象的作用范围 3.bean对象的生命周期 --> <!--创建bean的三种方法--> <!-- 第一种方法:使用默认构造函数创建 在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时 采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建 --> <!-- <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean> --> <!-- 第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器中) --> <!-- <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean> --> <!-- 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器) --> <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService"></bean> <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean> </beans>
两种工厂类
非静态工厂:对应bean.xml方案二
package com.itheima.factory; import com.itheima.service.IAccountService; import com.itheima.service.impl.AccountServiceImpl; /** * 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数) * */ public class InstanceFactory { public IAccountService getAccountService(){ return new AccountServiceImpl(); } }
静态工厂 :对应bean.xml方案三
package com.itheima.factory; import com.itheima.service.IAccountService; import com.itheima.service.impl.AccountServiceImpl; public class StaticFactory { static public IAccountService getAccountService(){ return new AccountServiceImpl(); } }
容器对象的作用范围和生命周期
<!-- bean的作用范围调整 bean标签的scope属性: 作用:用于指定bean的作用范围 取值: singleton:单例(默认) prototype:多例 request:作用于web应用的请求范围 session:作用于web应用的会话范围 global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,他就是session --> <!-- bean对象生命周期 单例对象 出生:当容器创建时对象出生 活着:只要容器还在,对象一直或者 死亡:容器销毁,对象消亡 多例对象 出生:当使用对象时spring框架创建(懒加载) 活着:对象在使用过程中一直活着 死亡:当对象长时间不用且没有其他对象引用时,由java的垃圾回收器回收 --> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>
以上的配置下,当AccountServiceImpl被初始化时和被销毁时,会自动类内调用以下方法
public void init(){ System.out.println("service中的对象init方法执行了"); } public void destroy(){ System.out.println("service中的对象destroy方法执行了"); }