初探Spring框架之———IOC

一、首先解释一下什么是Spring框架,以及Spring框架的作用

1、Spring框架:Spring是一个full-stack(一站式)的轻量级开源框架,以IOC(Inverse Of Control: 控制反转)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。简单来说,Spring是一个分层的JavaSE/EE full-stack 轻量级开源框架。

2、作用:解决企业应用开发的复杂性

3、优点:

1):方便解耦,简化开发 (高内聚低耦合)

Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理
spring工厂是用于生成bean

2):AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

3):声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无需手动编程

4):方便程序的测试

Spring对Junit4支持,可以通过注解方便的测试Spring程序

5):方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持

6):降低JavaEE API的使用难度

Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

二、什么是IOC?

1、IOC(Inversion of Control):就是控制反转。控制反转指的就是将对象的创建权交给了Spring来管理,其作用是实现了程序的解耦合(解耦)或者理解为降低了程序间的依赖关系,从而提高程序间的独立性,满足开闭原则,提高了可复用性和可修改性。可以解释为:原始的创建对象的方法都是使用new一个对象,这样就使得程序间的依赖关系很强,不方便修改和复用,所以我们常常采用工厂方法模式+反射+配置文件来改进,而IOC的底层原理就是使用工厂方法设计模式+反射+XML配置文件或注解来创建对象,只不过原始的创建对象的任务是交给程序员来编写,而现在使用Spring框架后,创建对象的任务就交给了Spring来管理。

2、关于IOC的一些细节

BeanFactory是Spring的IOC核心容器中的顶层接口,ApplicationContext是BeanFactory的子接口,这两个接口也是常用的创建bean对象的接口。

两者的区别:

ApplicationContext:一般是单例对象使用,它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象(开发通常采用这个接口)

BeanFactory:一般是多例对象使用,它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。

ApplicationContext常用的三个实现类:

ClassPathXmlApplicationContext:加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(常用)

FileSystemXmlApplicationContext:加载磁盘任意路径下的配置文件(必须有访问权限)

AnnotationConfigApplicationContext:用于读取注解创建容器的

3、Spring对bean的管理细节

1)、创建bean对象的三种方式:

第一种方式:使用默认构造函数创建。 在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。 采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。

eg:<bean id="对象名(accountService)" class="实现类的全限定类名(com.spring.service.impl.AccountServiceImpl)"></bean>

第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)

eg:<bean id="instanceFactory" class="com.spring.factory.InstanceFactory"></bean>

<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)

eg:<bean id="accountService" class="com.spring.factory.StaticFactory" factory-method="getAccountService"></bean>

注:上面所给出的id,class,factory-bean,factory-method属性值要根据自己的项目来写

2)、bean的作用范围

bean标签的scope属性

作用:用于指定bean的作用范围

取值: 常用的就是单例的和多例的

singleton:单例的(默认值)一个应用只有一个对象的实例。它的作用范围就是整个引用。 

prototype:多例的 , 每次访问对象时,都会重新创建对象实例。

request:作用于web应用的请求范围,web项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中

session:作用于web应用的会话范围,web项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中

global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session

eg:<bean id="accountService" class="com.spring.service.impl.AccountServiceImpl" scope="prototype"></bean> -->

3)、bean对象的生命周期

单例对象:scope="singleton"

出生:当容器创建时对象出生

活着:只要容器还在,对象一直活着

死亡:容器销毁,对象消亡

总结:单例对象的生命周期和容器相同

多例对象:scope="prototype"

出生:当我们使用对象时spring框架为我们创建

活着:对象只要是在使用过程中就一直活着。

死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收

eg:<bean id="accountService" class="com.spring.service.impl.AccountServiceImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>

4、spring 的依赖注入

依赖注入:(Dependency Injection)它是 spring 框架核心 ioc 的具体实现。 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。 简单的说,就是坐等框架把持久层(DAO)对象传入业务层(Service),而不用我们自己去获取。(再说通俗一点就是“赋值”)

能注入的数据有三类:基本类型和String其他bean类型(在配置文件中或者注解配置过的bean)、复杂类型/集合类型

注入的方式有三种:1)使用构造函数       2)使用set方法    3)使用注解

1)、构造函数的注入:(顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入)

使用的标签:constructor-arg

标签出现的位置:bean标签的内部

标签中的属性

type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型

index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始

name:用于指定给构造函数中指定名称的参数赋值(常用)

注:以上三个用于指定给构造函数中哪个参数赋值

value:用于提供基本类型和String类型的数据

ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

优势: 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。

弊端: 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

eg:

2)set方法注入(顾名思义,就是在类中提供需要注入成员的 set 方法)   最常用的方式

涉及的标签:property

出现的位置:bean标签的内部

标签的属性

name:用于指定注入时所调用的set方法名称

value:用于提供基本类型和String类型的数据

ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

优势: 创建对象时没有明确的限制,可以直接使用默认构造函数

弊端: 如果有某个成员必须有值,则获取对象是有可能set方法没有执行。

eg:数据类型为基本类型和String其他bean类型时:

数据类型为复杂类型/集合类型

三、基于注解的 IOC 配置

1、用于创建对象的

XML配置文件中:编写一个<bean>标签(如上创建bean对象的三种方式)

注解中:@Component注解 

作用:用于把当前类对象存入spring容器中

属性:  value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写

但在三层架构中spring框架为我们提供了具体的注解:

表现层:@Controller

业务层:@Service

持久层:@Repository

注:以上三个注解他们的作用和属性与Component是一模一样。

2、用于注入数据的

XML配置文件中:如上的三种方式,constructor-arg、property

注解中:

1):@Autowired(无属性)

作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功, 如果ioc容器

没有任何bean的类型和要注入的变量类型匹配,则报错(因为IOC容器是一个Map结构

出现的位置:可以是变量上,也可以是方法上

2):@Qualifier

作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用(必须结合@Autowired使用)。但是在给方法参数注入时可以

属性:value:用于指定注入bean的id 

例如:

3):@Resource

作用:直接按照bean的id注入。它可以独立使用

属性:name:用于指定bean的id。

注: 以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现, 另外,集合类型的注入只能通过XML来实现

4):@Value(可以注入基本类型和String类型的数据)

作用:用于注入基本类型和String类型的数据

属性: value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式),SpEL的写法:${表达式}

3、用于改变作用范围的

XML配置中:scope属性

注解中:@Scope

作用:指定bean的作用范围

属性:value:指定范围的取值。常用取值:singleton prototype(如注解一样)

4、用于改变生命周期的

XML配置中:init-method、destroy-method属性

注解中:

@PostConstruct:用于指定初始化方法

@PreDestroy:用于指定销毁方法

 

发布了16 篇原创文章 · 获赞 8 · 访问量 9805
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章