Spring(一)Spring概述和基于XML的IoC配置

一、Spring概述

1.1 spring是什么

  • Spring 是分层的 Java SE/EE full-stack 轻量级开源框架,以 IoC(Inverse of Control,控制反转)和 AOP(Aspect Oriented Programming,面向切面编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多 著名的第三方框架和类库。

1.2 spring的优势

1)方便解耦,简化开发
  通过 Spring提供的 IoC容器,可以将对象间的依赖关系交由 Spring进行控制,避免硬编码所造 成的过度程序耦合
2)AOP编程的支持
  Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。
3)声明式事务的支持
  只需要通过配置就可以完成对事务的管理,而无须手动编程。
4)方便程序的测试
  可以用非容器依赖的编程方式进行几乎所有的测试工作。
5)方便集成各种优秀框架
  Spring可以降低各种框架的使用难度,提供了对各种优秀框架的直接支持。
6)降低 JavaEE API的使用难度
  Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的 使用难度大为降低。

1.3 spring的体系结构

在这里插入图片描述
上述包含了Spring框架的所有模块,这些模块可以满足一切企业级应用开发的需求。下面分别对这些模块进行简单介绍。
1)Data Access/Integration(数据访问/集成)
数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块。

  • JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
  • ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate 和 iBatis 提供了的集成层。
  • OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
  • JMS 模块:指 Java 消息服务,包含的功能为生产和消费的信息。
  • Transactions 模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。

2)Web模块
Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件。

  • WebSocket 模块:为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。
  • Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
  • Web 模块:提供面向web的基本功能和面向web的应用上下文。
  • Portlet 模块:类似于Servlet模块的功能,提供了Portlet环境下的MVC实现。

3)Core Container(核心容器)
Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和Spring Expression Language 表达式语言模块组成

  • Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
  • Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
  • Context 模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。
  • SPEL 模块:提供了强大的表达式语言去支持运行时查询和操作对象图。

4)其他模块

  • AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
  • Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
  • Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
  • Messaging 模块:该模块提供了对消息传递体系结构和协议的支持。
  • Test 模块:支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。

二、IoC容器的概念和作用

2.1 控制反转——IoC

  • 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
  • 简单来说就是说我将 new 对象的这个权利,由原来对象本身转移到 Spring 身上。 举个例子: Service A 调用 Dao B 的时候, 如果不用 Spring 的话, 那肯定要有 Service A 去 new 一个 Dao B 对象出来, 再去调用。但如果用了 Spring 后, 我们 new Dao B 这个过程就已经由Spring 处理好。
  • 依赖注入: 是说你不用创建对象,而只需要描述它如何被创建, 简单讲就是帮助 new 对象并且管理这些对象。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC 容器)负责把他们组装起来 。
  • IoC优点:IOC 或依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和 JNDI 查找机制。最小的代价和最小的侵入性使松散耦合得以实现。

2.2 spring的依赖注入

  • 依赖注入的方式:常用的有 构造器注入, set方式注入,基于注解的注入。
  1. 构造函数注入
      使用的标签:constructor-arg
      标签出现的位置:bean标签的内部
      标签中的属性
      type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
      index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
      name:用于指定给构造函数中指定名称的参数赋值    (常用的)
      value:用于提供基本类型和String类型的数据
      ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
      优势
        在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
      弊端
        改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
    示例:
	/**************AccountServiceImpl.java*************/
	public class AccountServiceImpl implements IAccountService {
	    //如果是经常变化的数据,并不适用于注入的方式
	    private String name;
	    private Integer age;
	    private Date birthday;
	
	    public AccountServiceImpl(String name,Integer age,Date birthday){
	        this.name = name;
	        this.age = age;
	        this.birthday = birthday;
	    }
	    public void  saveAccount(){
	        System.out.println(name+","+age+","+birthday);
	    }
	}
	/*****************bean.xml***********************/
    <bean id="accountService" class="com.wink.service.impl.AccountServiceImpl">
        <constructor-arg name="name" value="叶子"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>
  1. set方法注入
      涉及的标签:property
      出现的位置:bean标签的内部
      标签的属性
        name:用于指定注入时所调用的set方法名称
        value:用于提供基本类型和String类型的数据
        ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
      优势
        创建对象时没有明确的限制,可以直接使用默认构造函数
      弊端
        如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
    示例:
	/**************AccountServiceImpl.java*************/
	public class AccountServiceImpl implements IAccountService {
	    //如果是经常变化的数据,并不适用于注入的方式
	    private String name;
	    private Integer age;
	    private Date birthday;
	
	    public void setName(String name) {
	        this.name = name;
	    }
	
	    public void setAge(Integer age) {
	        this.age = age;
	    }
	
	    public void setBirthday(Date birthday) {
	        this.birthday = birthday;
	    }
	
	    public void  saveAccount(){
	        System.out.println(name+","+age+","+birthday);
	    }
	}
	/*****************bean.xml***********************/
    <bean id="accountService" class="com.wink.service.impl.AccountServiceImpl">
        <property name="name" value="叶子" ></property>
        <property name="age" value="21"></property>
        <property name="birthday" ref="now"></property>
    </bean>
  • 注入集合属性
    就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合
      用于给List结构集合注入的标签:list,array ,set
      用于个Map结构集合注入的标签: map ,props
      结构相同,标签可以互换
  1. @Autowired:自动装配
      主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:
    @Component:可以用于注册所有bean
    @Repository:主要用于注册dao层的bean
    @Controller:主要用于注册控制层的bean
    @Service:主要用于注册服务层的bean
      描述依赖关系主要有两种:
      @Resource和@Autowired

三、Spring基于XML的IoC配置

3.1 spring中工厂的类结构图

在这里插入图片描述
在这里插入图片描述

3.2 BeanFactory和ApplicationContext的区别

  • BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。
  • ApplicationContext 是 BeanFactory 的子接口,也被称为应用上下文。它不仅提供了 BeanFactory 的所有功能,还添加了对 i18n(国际化)、资源访问、事件传播等方面的良好支持。
  • BeanFactory 和 ApplicationContext 的区别: 创建对象的时间点不一样。
      ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
      BeanFactory:什么使用什么时候创建对象。
  • ApplicationContext 接口有三个常用的实现类:
    1)ClassPathXmlApplicationContext
      该类从类路径 ClassPath 中寻找指定的 XML 配置文件,找到并装载完成 ApplicationContext 的实例化工作。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);

  2)FileSystemXmlApplicationContext
  该类从指定的文件系统路径中寻找指定的 XML 配置文件,找到并装载完成ApplicationContext 的实例化工作。

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

  3)AnnotationConfigApplicationContext
  当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

3.3 IoC中的bean标签

3.3.1 bean的配置及常用属性
  • 用于配置对象让 spring 来创建的.默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
    定义 Bean 的示例代码:
<?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">
        <!-- 使用id属性定义user,其对应的实现类为com.wink.domain.User -->
    	<bean id="user" class="com.wink.domain.User" />
</beans>

< bean>元素的常用属性:

名称作用
id给对象在容器中提供一个唯一标识。用于获取对象
class 指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数
scope用于设定 Bean 实例的作用域,其属性值有 singleton(默认值,单例)、prototype(多例)、request、session 和 global Session。
property< bean>元素的子元素,用于调用 Bean 实例中的 Set 方法完成属性赋值,从而完成依赖注入。该元素的 name 属性指定 Bean 实例中的相应属性名
constructor-arg< bean>元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type 属性指定构造参数的类型
ref< property>和< constructor-arg>等元素的子元索,该元素中的 bean 属性用于指定对 Bean 工厂中某个 Bean 实例的引用
value< property> 和< constructor-arg>等元素的子元素,用于直接指定一个常量值
init-method指定类中的初始化方法名称
destroy-method指定类中销毁方法名称
3.3.2 bean的作用范围和生命周期

单例对象:scope=“singleton”
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
   对象出生:当应用加载,创建容器时,对象就被创建了。
   对象活着:只要容器在,对象一直活着。
   对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope=“prototype”
每次访问对象时,都会重新创建对象实例。
生命周期:
   对象出生:当使用对象时,创建新的对象实例。
   对象活着:只要对象在使用中,就一直活着。
   对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。
在这里插入图片描述
Bean 生命周期的整个执行过程描述:

1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。

2)利用依赖注入完成 Bean 中所有属性值的配置注入。

3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。

4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。

5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。

6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。

7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。

8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。

9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。

10)如果在 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。

11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

3.3.3 bean的实例化的三种方式

第一种:使用默认的无参构造函数
在默认情况下:它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。如:

<bean id="accountService" class="com.wink.service.impl.AccountServiceImpl"/>

第二种:使用静态工厂的方法创建对象

//模拟一个静态工厂,创建业务层实现类
public class StaticFactory{
	public static IAccountService createAccountService(){
		return new AccountServiceImpl();
	}
}
<!-- 此种方式是:
		使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器   
		id 属性:指定 bean 的 id,用于从容器中获取   
		class 属性:指定静态工厂的全限定类名   
		factory-method 属性:指定生产对象的静态方法
	-->
<bean id="accountService"  
	  class="com.wink.factory.StaticFactory"
	  factory-method="createAccountService"/>

第三种:使用实例工厂的方法创建对象

/**
 *模拟一个实例工厂,创建业务层实现类  
 * 此工厂创建对象,必须现有工厂实例对象,再调用方法  
*/ 
public class InstanceFactory {  
	 public IAccountService createAccountService(){   
		 return new AccountServiceImpl();  
	 } 
} 
 <!-- 此种方式是:    
	 先把工厂的创建交给 spring来管理,然后在使用工厂的bean来调用里面的方法   
	 factory-bean 属性:用于指定实例工厂bean的id。   
	 factory-method 属性:用于指定实例工厂中创建对象的方法。  
 --> 
<bean id="instancFactory" class="com.wink.factory.InstanceFactory"/>
<bean id="accountService"      
	  factory-bean="instancFactory"      
	  factory-method="createAccountService"/>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值