spring 零:基本原理

目录

 

框架特征与功能

Spring的组成:

Spring IOC基础:

SpringIOC容器读取方式分为两种:

Spring IoC实现方式:

XML方式中的常见属性:

注解方式:

常见面试问题:

什么是IOC?

那么IOC容器中Bean的生命周期?

@Resource装配顺序★★★★


框架特征与功能

  1. 轻量:从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的对象不依赖特定类:典型地,Spring应用中的对象不依赖于Spring的特定类。
  2. 控制反转IOC:基础题Spring通过一种称作控制反转(IoC(Inversion of Control作用:解耦)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
  3. 面向切面AOP:Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

     

Spring的组成:

  1. 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  2. Spring上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  3. Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  4. Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。与ORM差不多
  5. Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  6. Spring Web模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  7. Spring MVC框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

     

Spring IOC基础:

控制反转IoC(Inversion of Control):是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。Spring容器在初始化时先读取配置文件根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

SpringIOC容器读取方式分为两种:

  1. BeanFactory:接口BeanFactory为IOC容器提供了基础功能,Spring文档中提到,当前该类仅仅是为了向后兼容老的版本,除非你有更好的原因否则就应该使用第二种容器。
  2. ApplicationContext:二代版本,接口通过API文档可以知道,ApplicationContext是BeanFactory的子接口,并且从文档中也可以看到ApplicaionContext除了包含有BeanFactory的所有功能还支持了更多的功能。
    1. ApplicationContext的实现有四种方式:(实现类)

      FileSystemXmlApplicationContext:加载配置文件的时候采用的是项目的路径。★

      ClassPathXmlApplicationContext:加载配置文件的时候根据ClassPath位置。★

      XmlWebApplicationContext:在Web环境下初始化监听器的时候会加载该类。

      AnnotationConfigApplicationContext:根据注解的方式启动Spring容器。★

Spring IoC实现方式:

  1. XML方式之-----属性方式
  2. XML方式之-----构造器方式
  3. 注解方式:

XML方式中的常见属性:

Bean元素:一个标签bean对应的就一个类对象,通过id(或者Name)以及Class来定位一个类,这边Class要求是完全限定类名。

名称

解释

id

对象名

class

对象的完整类路径

name

等同于id,用于指定bean的别名不推荐使用

singleton

用于指定当前Bean的创建模式

true表示为单例模式

false表示原型模式(prototype),BeanFactory将为每次Bean请求创建一个新的Bean实例。

depends-on

用于指定当前Bean的依赖Bean,强制指定的Bean在当前Bean初始化之前先完成初始化

init-method

用于指定当前Bean的初始化方法,在Bean实例创建好后,首先会调用其指定名称的方法默认为无参构造器

destory-method

用于指定当前Bean的销毁方法,在Bean即将被销毁之前会自动调用该属性指定的方法

scope

对象的生命周期作用域:

singleton:默认的,每个IOC容器作用域中一个bean定义只对应一个对象实例

prototype:一个bean定义对应多个对象实例

request:一个bean定义作用于HTTP的Request生命周期;是指每个HTTP的Request拥有自己的通过一个bean定义创建的实例。仅在web中有效

session:一个bean定义作用于HTTP的Session生命周期;是指每个HTTP的Session拥有自己的通过一个bean定义创建的实例。仅在web中有效

application:一个bean定义作用于HTTP的Application生命周期;是指每个HTTP的Application拥有自己的通过一个bean定义创建的实例。仅在web中有效不推荐

lazy-init

用于指定当前Bean的初始化时间,若值为true表示在初次调用时才会自动创建实例并初始化,false表示在IoC容器创建的时候就会完成创建和初始化默认为创建时初始化

autowire

用于指定当前Bean的依赖关系的自动注入方式,其有五个值:

byName值:表示通过id名称来自动匹配;

byType值:表示通过class指定的类型来自动装配;

constructor值:表示使用构造函数的参数进行自动装配(参数的类型匹配);

autodetect值:表示自动进行选择匹配方式,首先进行constructor自动装配,若不存在构造方法则使用byType方式进行自动装配;

no值:表示不适用自动装配。

 

Property元素:属性标签,负责给对象属性赋值

名称

解释

name

属性

value

给属性赋值

ref

通过使用ref标记指定bean属性的目标bean

value标签

用于指定属性的值,类型为基本类型、字符串类型,值为标签内的文本内容,可以使用null值将属性的值设置为null

ref标签

用于指定属性的值,类型为引用对象类型,值为其属性的值,其属性有以下三种:

local属性:用于指定依赖本地Bean实例,即同一XML文件中定义的Bean

bean属性:用于指定依赖的Bean实例,可以是不同XML文件中的Bean

parent属性:用于指定依赖的Bean实例,可以是当前BeanFactoryApplicationContext的父BeanFactoryApplicationContext中的Bean

list标签

用于声明该依赖对象为一个list集合,其下用valueref标签来指定list中的各值

set标签

用于声明该依赖对象为一个set集合,其用法与list标签相同。

map标签

用于声明该依赖对象为一个map集合,其下用entry标签来声明一个键值对

entry标签:用于声明map集合下的一个键值对,其下用key属性指明键,value/ref标签指明值

key属性:用于指明键值对中的键,它一般为字符串

value标签:用于指明键值对中的值,类型为基本类型、字符串类型

ref标签:用于指明键值对中的值,类型为引用对象类型,即其他的Bean,其用法同之前的ref标签

 

注解方式:

需要注意的是,注解方式需要进行自动装配才能完成

<!--指定要扫描的包,如果有多个可以用逗号隔开-->
<context:annotation-config/><!--开始加载注释-->
<context:component-scan base-package="被自动检索的包" />

常见注解:

 

名称

解释

@Component

启动Spring后,会自动把它转成容器管理的Bean (产生对象)(当不指定对象名时,生成的对象为类名小写)

@Repository

用于对DAO实现类进行注解。(产生对象)基本不用

@Service

用于对业务层注解,但是目前该功能与 @Component 相同。(产生对象)

@Controller

用于对控制层servlet注解,但是目前该功能与 @Component 相同(产生对象)

@Scope

作用域,等同于XML中的scope与以上四个共同使用

写法例如:

@Component(ui)

@Scope(prototype)

@Resource

默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入都是ref的意思给属性赋值的

@Autowired

默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;给属性赋值的

@Qualifier

@Qualifier("XXX") 中的 XX是 Bean 的名称,所以 @Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。给属性赋值的

示例:

配置demo.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"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans.xsd 
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context.xsd">
	
		
	<context:annotation-config/><!--开始加载注释-->
	<context:component-scan base-package="demo" /><!--指定检索demo包下的注解-->
</beans>

书写封装类: 

package demo;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;

@Component    //注解方式生成对象,其对象名为小写的类名
public class DemoC1 {
	@Resource(name="demoC2")    //给demoC2赋值,在容器中查询一个名为demoC2的对象并赋给属性
	private DemoC2 demoC2;

	@Override					//重载
	public String toString() {
		return "DemoC1 [demoC2=" + demoC2 + "]";
	}
}
package demo;
import org.springframework.stereotype.Component;

@Component			//生成一个demoC2的对象
public class DemoC2 {
}

 测试:从容器中取出对象

package demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	public static void main(String[] args) {
		ApplicationContext bean= new ClassPathXmlApplicationContext("Demo.xml");
		System.out.println(bean.getBean("demoC1"));        //从spring容器得到demoC1对象并输出
	}
}

常见面试问题:

什么是IOC?

(1).IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。 对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。  

(2).在Spring的工作方式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

(3).在系统运行中,动态的向某个对象提供它所需要的其他对象。  

(4).依赖注入的思想是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。 总而言之,在传统的对象创建方式中,通常由调用者来创建被调用者的实例,而在Spring中创建被调用者的工作由Spring来完成,然后注入调用者,即所谓的依赖注入or控制反转。 注入方式有两种:依赖注入和设置注入; IoC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象。

(5).实现:注解,构造器,xml

那么IOC容器中Bean的生命周期?

Bean的生命周期包括Bean的定义,Bean的初始化,Bean的使用,Bean的销毁

Bean的定义:一般Bean使用XML文件的方式进行定义,定义的时候将Bean之间的依赖关系和属性的赋值都进行了定义

Bean的初始化:其实Bean的初始化包括Bean的创建和初始化两个方法,Bean的创建和初始化一般是同步进行的,Bean在完成创建后直接就会进行初始化操作,创建的时机与Bean的lazy-init属性的设置有关。

Bean的使用:在web程序运行期间,发生对某一个Bean的调用时,就会使用这个Bean实例,如果使用编码的方式来获取Bean同样也是Bean的使用,Bean的编码使用方式有三种,第一种是使用BeanWarpper,第二种是使用BeanFactory,第三种就是使用ApplicationContext。

Bean的销毁:Bean实例在程序退出的时候会进行销毁,而在销毁之前会自动调用Bean的destory-method属性指定名称的方法。

@Resource装配顺序★★★★

如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值