Spring01--Spring框架

本文深入解析Spring框架的核心概念,包括IoC(控制反转)、DI(依赖注入)以及bean的生命周期和管理。Spring通过IoC容器负责对象的创建、初始化,使用DI建立bean间的依赖关系。讲解了bean的作用域、实例化方式以及单例模式可能引发的线程安全问题。同时,介绍了setter注入和构造器注入,并提到了自动装配的概念。此外,还讨论了bean的生命周期管理和关闭容器的方法,确保bean的初始化和销毁操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、系统架构

请添加图片描述
包含核心模块:

  • 核心容器(Core Container)
    Spring的核心模块,其他的都需要依赖该模块
  • AOP
    面向切面编程,它依赖核心层容器,目的是“在不改变原有代码的前提下对其进行功能增强”
    Aspects:AOP是思想,Aspects是对AOP思想的具体实现
  • 数据层
    开发与整合
    1)Data Access:数据访问
    2)Data Integration:数据继承,支持整合其他的数据层解决方案
  • 事务管理
    3)Transactions:事务
  • 表现层开发与整合
    web层:SpringMVC框架
    Test层:整合Junit完成单元测试和集成测试

Spring框架的主要功能:
用来管理对象,基于对象管理的前提下,对管理的对象进行功能的增强

2、核心概念

1、IoC什么意思?
使用对象时由 开发者使用new 创建对象 转换为由 外部提供对象,这种思想成为控制反转(IoC)
2、Spring和IoC的关系是什么?
Spring对IoC思想进行实现
Spring提供容器称为IoC容器,充当IoC思想中的外部。
3、Ioc容器作用以及内部存放什么?

  1. Ioc容器负责对象的创建、初始化等一系列工作,其中包含数据层和业务层的类对象
  2. 被创建或被管理的对象在Ioc容器中统称为Bean
  3. Ioc容器中存放Bean对象

4、Ioc中创建好Service和dao对象后就能执行了吗?
不行,service运行需要依赖dao对象,此时这个关系的建立用到DI。
5、DI是什么意思?
在Spring的IoC容器中,根据要求,建立bean与bean之间的依赖关系的过程成为依赖注入DI

入门案例

都没有new对象

<!--id属性在同一个上下文(配置文件)中不能重复
 bean标签表示配置bean
 id属性表示给bean起名字
 class属性表示给bean定义类型 某种程度上,Dao在哪需要被创建,class就定位到哪-->
<bean id = "bookDao" class = "com.endorphin.dao.Impl.BookDaoImpl"/>
<bean id = "bookService" class = "com.endorphin.service.Impl.BookServiceImpl">
	<!--DI依赖注入
		配置service与dao的关系
		property标签表示配置当前bean的属性
		name属性表示配置哪一个具体的属性 对象的类型
		ref属性表示参照哪一个bean bean的id-->
		<property name = "bookDao" ref = "bookDao"/>
</bean>
//BookServiceImpl类
public class BookServiceImpl implement BookService{
	//private BookDao bookDao = new  BookDaoImpl()
	//删除业务层中使用new方式创建的dao对象
	private BookDao bookDao;
	@override
	//....
	//提供对应的set方法因为没有new对象
	public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}
//主方法 没有用DI
psvm{
	//获取IoC容器
	ApplicationContext ctx = new ClassPathXmlAllicationContext("applictionContext.xml");
	//bean对象
	BookService bookservice = ()ctx.getBean("bookService");
	bookservice.save();
}

3、IoC相关内容

1、Spring创建的对象默认是单例对象。如果想修改成非单例对象,通过scope属性进行“prototype”
2、封装属性的实体类是否需要配置成bean?
由于实体类用于封装属性,每个实体类对象保存的数据均不相同,不适合交给Spring容器管理,因此不建议配置成bean

bean基础配置

请添加图片描述
class属性不能写接口的全类名,因为接口不能创建对象

  • 什么bean默认为单例?
    • bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
    • bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
  • bean在容器中是单例的,会不会产生线程安全问题?
    • 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,
    • 因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
    • 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,
    • 因方法中的局部变量在方法调用完成后就会被销毁,所以不会存在线程安全问题。
  • 哪些bean对象适合交给容器进行管理?
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具对象
  • 哪些bean对象不适合交给容器进行管理?
    • 封装实例的域对象,因为会引发线程安全问题,所以不适合。
    • 可以在不同Servlet之间传递数据的对象,就是域对象。只要是域对象都有如下方法:
      setAttribute(name,value);存储数据的方法
      getAttribute(name);根据name获取对应数据值
      removeAttribute(name);删除数据

bean别名配置

name为bean指定别名,别名可以有多个,使用逗号、分号、空格进行分隔

bean作用范围配置

scope为bean设置作用范围,可选值为单例singloton,非单例prototype

getBean中根据bean标签的id属性和name属性的任意一个值来获取bean对象

获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionException

为什么bean默认为单例?

  • bean为单例的意思是在Spring的IoC容器中只会有该类的一个对象
  • bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高

bean在容器中是单例的,会不会产生线程安全问题?

如果对象是有状态对象,即该对象有成员变量可以用来存储数据,因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
如果对象时无状态对象,即该对象没有成员变量、没有进行数据存储,因为方法中的局部变量在方法调用完成后就会被销毁,所以不会存在线程安全问题。

4、bean实例化

以上只说明对象已经能交给Spring的IoC容器创建了,并没有指明容器是如何创建对象的。

构造方法实例化

通过一系列实验证明,Spring底层采用反射、类的无参构造方法。构造方法在类中默认会提供,如果重写了构造方法,默认的就会消失,最好也重写默认的构造方法。

静态工厂初始化(了解)

实例工厂与FactoryBean

实例工厂类中的方法不是静态方法,还需要在xml中配置bean,用FactoryBean来简化开发。

//创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //代替原始实例工厂中创建对象的方法
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }
    //返回所创建类的Class对象
    public Class<?> getObjectType() {
        return UserDao.class;
    }
}

实现FactoryBean接口,提供泛型类型,泛型类型即当前FactoryBean创建的对象类型。
Spring的FactoryBean接口其实有三个方法,还有一个是设置对象是否Wie单例,默认true。

5、bean的生命周期

bean的生命周期是bean对象从创建到销毁的整体过程。bean的生命周期控制的是在bean创建后到销毁前做一些事情。

bean初始化对应的代码执行,bean销毁前对应的代码未执行,原因:
Spring的IOC容器是运行在JVM中,运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器中获取bean对象然后调用方法执行,main方法执行完后,JVM退出,这时候IOC容器中的bean还没有来得及销毁就已经结束了,所以没有调用对应的destroy方法。

解决办法:
1、close关闭容器。由于ApplicationContext中没有close方法,需要将ApplicationContext更换为ClassPathXmlApplicationContext。
2、注册钩子关闭容器
在容器未关闭之前,提前设置好回调函数,让虚拟机在退出之前回调此函数来关闭容器。调用ctx的registerShutdownHook()方法.

6、DI相关内容(两种注入方式)

setter注入

注入引用数据类型:在bookServiceImpl对象中引入UserDao

在类中声明属性、提供set方法,在xml中提供property即可。

注入简单数据类型

在类中声明对应的简单数据类型的属性,并提供对应的setter方法。xml中写property标签

构造器注入(了解)

添加带参数的构造方法,xml中添加标签constructor-arg

7、自动配置

什么是依赖自动装配

IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配。

自动装配方式有哪些

按类型、按名称、按构造方法、不启用自动装配

在xml中删除property标签,在bean中添加autowire属性。autowire属性开启自动装配,通常使用按类型装配。

注意:

  • 需要注入属性的类中对应属性的setter方法不能省略
  • 被注入的对象必须要被Spring的IOC容器管理
  • 按照类型在Spring的IOC容器中如果找到多个对象,会报错。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值