Spring 学习笔记 Part02
3. 使用 Spring 的 IoC 解决程序耦合
加入spring的maven坐标,并配置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="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"/>
</beans>
bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中
id 属性:对象的唯一标识。
class 属性:指定要创建对象的全限定类名
获取 Spring 的 IoC 核心容器,并根据 id 获取对象。
3.1 ApplicationContext
ApplcationContext有三个常用实现类:
ClassPathXmlApplcationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。
FileSystemXmlApplcationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)。
AnnotationConfigApplcationContext:它是用于读取注解创建容器的,是之后小节的内容。
//1.获取核心容器对象
ApplicationContext ac = new ClaassPathXmlApplcationContext("bean.xml");
//2.根据id获取Bean对象
AccountDao dao = ac.getBean("accountDao",AccountDao.class);
3.2 BeanFactory
Resource resource = new ClassPathResource("bean.xml");
//1.获取核心容器对象
BeanFactory factory = new XmlBeanFactory(resource);
//2.根据id获取Bean对象
AccountDao dao = (AccountDao)factory.getBean("accountDao");
两者的区别总结
这两个核心容器都是通过反射来创建对象。
//ApplicationContext:
单例对象使用。(也可以灵活支持多例对象)
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
//BeanFactory:
多例对象使用。
它在构建核心容器时,创建对象采用的策略是采用延迟加载的方式。也就是说,什么时候根据 id 获取对象,什么时候才真正的创建对象。
4. Spring 对 bean 的管理细节
4.1 创建 bean 的三种方式
第 1 种方式:使用默认构造函数创建
在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时,采用的就是默认无参构造函数创建bean对象。
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>
bean标签
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数
(类似Map,通过id -> class,框架再用class来反射创建对象)
此时如果类中没有默认无参构造函数,则对象会创建失败。
但很多要使用的类是存在于jar包中的,我们无法通过修改源码的方式来提供默认无参构造函数,则就有了第二种方式。
第 2 种方式:使用普通工厂(实例工厂)中的方法创建对象
即使用某个类中的方法创建对象,并存入spring容器。
模拟工厂类
public class InstanceFactory{
public AccountService getAccountService(){
return new AccountServiceImpl();
}
}
bean.xml配置
<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"/>
<bean id="accountService" factory-bean="inistanceFactory" factory-method="getAccountService" />
bean标签
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-bean 属性: 指定实例工厂bean 的 id
factory-method 属性:指定生产对象的静态方法
第 3 种方式:使用静态工厂的方法创建对象
即使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器。
静态工厂类
public class StaticFactory {
public static AccountService createAccountService(){
return new AccountServiceImpl();
}
}
bean.xml配置
<bean id="accountService" class="com.itheima.factory.instanceFactory" factory-method="getAccountService" />
bean标签
id 属性:指定 bean 的 id,用于从容器中获取
class 属性:指定静态工厂的全限定类名
factory-method 属性:指定生产对象的静态方法
问:上述方法 2 和方法 3 的 get/create 方法都用到了 new 关键字,这不是耦合了吗?
请把这些模拟工厂看成是jar包中的类,在今后开发中大量都是使用jar包,在jar包中的类都不是.java文件,而是.class文件,都是修改不了的,是不存在依赖性的。
在今后开发中,许多对象是需要通过一个类的返回值来获取的,这种通过返回值获取对象的方式,采用的就是方法 2 与方法 3。
4.2 bean 对象的作用范围
//scope属性:指定对象的作用范围。
singleton :单例的(默认值)
prototype :多例的
request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么globalSession 相当于 session (全局Session例如可用于例如登录验证码的负载均衡)
//bean标签的其他属性
init-method:指定类中的初始化方法名称
destroy-method:指定类中销毁方法名称
4.3 bean对象的生命周期
//单例对象 scope="singleton"
出生:当容器创建时对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡
总结:单例对象的生命周期和容器相同
//单例对象 scope="prototype"
出生:当我们使用对象时Spring框架为我们创建
活着:对象只要是在使用过程中就一直活着
死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收机制回收
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84503.html