1.spring概述
1.1什么是Spring
Spring是一个轻量级的Java开发框架,解决企业级应用开发的逻辑层和其他各层的耦合问题,Spring框架为开发java应用程序提供全面的基础框架支持。解决企业级应用开发的发杂性,简化Java开发。
1.2 Spring两大核心概念
IOC/DI
IOC :控制翻转,他就是不会直接创建对象,只是将对象声明出来,在代码中不直接与对象和服务进行连接,但是在配置文件中描述了哪一项组件需要哪一项服务,容器将他们组件起来,在一般的IOC场景中容器创建了所有的对象(将创建对象的权力交给Spring),并设置了必要的属性将他们联系起来(id ,class,name),等到使用的时候才把他们声明起来。
DI:依赖注入
AOP:面向切面编程
1.3 从Spring容器中获取Spring通过IOC管理的对象三种方式)
bean 被管理的对象
容器 放置所有管理的对象
方式一:根据Bean的id值获取
//方式一:根据Bean的id值获取对象
cn.zqwl.pojo.dept emp1 = (cn.zqwl.pojo.dept) cp.getBean("dept2");
System.out.println(emp1);
方式二:根据Bean的类对象获取,容器中只有一个该类型的对象可以通过类型获取
//方式二:根据Bean的类对象获取对象,
// 注意:
// 容器中只有一个该类型的对象可以通过类型获取
dept bean = cp.getBean(dept.class);
System.out.println(bean);
方式三:根据Bean的id值、类对象获取
//方式三:根据Bean的id值、Bea的类对象获取对象
dept dept2 = cp.getBean("dept2", dept.class);
System.out.println(dept2);
1.4 创建对象的方式(两种)
通过BeanFactory创建对象(单纯的创建一个对象)(Spring创建)
通过FactoryBean创建对象,自定义创建对象的工厂(将工厂交给Spring管理)极端的情况使用
1.5 属性注入
构造器注入:通过有参构造方法给bean的属性赋值
注意:传几个参数在相应的类中也应该提供几参构造方法,否则报错
<!-- constructor-arg:用于指定 Bean 的构造函数参数值 type:指定构造函数参数的类型。 index:指定构造函数参数的位置,从 0 开始计数。 name:指定构造函数参数的名称,主要用于有多个相同类型的参数的情况。 value:指定构造函数参数的常量值。 ref:指定构造函数参数的引用值,引用其他 Bean。Spring管理的Bean -->
<bean name="emp" class="cn.zqwl.pojo.emp">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="password" value="123456"></constructor-arg>
</bean>
设值注入:通过setter方法赋值,创建对象后,调用set方法完成属性的赋值,
注意:如果类中没有提供set方法,则无法使用设值注入的方式为属性赋值。所有相应的类中必须提供set方法。
<!-- 1. id:每个bean都必须有一个唯一的标识符,用于在应用程序中引用该bean。 2. name:bean属性的名称,可以有多个。 3. value:bean属性的值,可以是任何原始类型或字符串。 4. ref:bean属性的引用类型值,指向另一个bean。可以使用该bean的id或名称指定。 -->
<bean name="emp2" class="cn.zqwl.pojo.emp">
<property name="id" value="1"></property>
<property name="password" value="张三"></property>
<property name="name" value="123456"></property>
</bean>
1.6 集合类型注入
<bean name="assemble" class="cn.zqwl.pojo.assemble">
<property name="list" >
<list>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
</list>
</property>
<property name="set" >
<set>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
</set>
</property>
<property name="a" >
<array>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
</array>
</property>
<property name="map">
<map>
<entry key="1" value="1"></entry>
<entry key="2" value="2"></entry>
<entry key="3" value="3"></entry>
<entry key="4" value="4"></entry>
</map>
</property>
</bean>
1.7 自动注入 注入和被注入都是Spring管理的bean
在beans添加(全局配置)
<!-- 1.不自动注入 default-autowire="no" default-autowire="default" 2.default-autowire="byname" 根据名字自动注入(属性名和注入bean的id相同) 3.default-autowire="byClass"根据属性类型自动注入(属性类型和注入bean的类型相同) 4.default-autowire=“constructor”:根据(有参)构造方法自动注入 先根据属性名获取相应的bean 如果更具属性名没找到对应的bean,根据类型找到响应的bean -->
在bean标签中(局部配置)
<!-- 1.no:不自动注入 2.default:默认使用全局配置自动配置 3.byname 根据名字自动注入(属性名和注入bean的id相同) 4.byClass根据属性类型自动注入(属性类型和注入bean的类型相同) 5.constructor:根据(有参)构造方法自动注入 -->
注意:两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖依赖。
1.8 scope属性
singleton:默认的情况下加载spring配置文件,完成对象创建的对象,存放在Spring容器中,只创建 一个对象,单例设计模式(需要考虑线程安全,所有程序共享).
prototype:获取对象时完成对象的创建,存放在Spring容器中。获取一次创建一次,原型设计模式
1.9 BeanFactory 和 ApplicationContext区别
<!-- BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档, 管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。 ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具的功能外,还提 供了更完整的框架功能 加载方式 BeanFactroy采用的是延迟加载形式来注入Bean的(懒汉式),即只在使用到某个Bean时(调用 getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置 问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用 getBean方法才会抛出异常。 ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动 时,我们就可以发现Spring中存在的配置错误,这样利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所的单实例Bean,通过预载入单实例bean ,确保当你需 要的时候,你就不用等待,因为它们已经创建好了。(饿汉式) 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多 时,程序启动较慢。 -->
1.10 Spring循环依赖
Spring循环依赖是指两个或多个Bean之间存在相互依赖的情况,即A依赖B,B又依赖A。这种情况称为循环依赖。Spring使用三级缓存解决循环依赖问题。
三级缓存主要有以下三个:
1. singletonObjects(一级):缓存已经创建完成的Bean对象。
2. earlySingletonObjects(二级):缓存已经创建完成但是被提前暴露出来的Bean对象,用于处理循环依赖问题。
3. singletonFactories(三级):缓存已经创建完成但是需要进一步处理的Bean对象。
当创建一个Bean对象时,Spring需要检查其依赖的其他Bean对象是否已经创建。如果存在循环依赖,则Spring会先创建完成依赖的Bean对象,然后再进行循环依赖的解决。
当A的bean需要B的bean的时候,提前将A的bean放在缓存中(实际是将A的ObjectFactory放到三级缓存),
然后再去创建B的bean,但是B的bean也需要A的bean,那么这个时候就去缓存中拿A的bean,B的bean创建完毕后,
再回来继续创建A的bean,最终完成循环依赖的解决。
通过三级缓存的机制,Spring可以解决循环依赖问题。但是如果循环依赖关系比较复杂,可能会导致性能问题。因此,建议在设计Bean之间的依赖关系时,尽量避免出现循环依赖。