Spring简介和IOC容器使用

Spring简介

介绍

  • spring是一个开源框架,使用Spring开发可以将Bean对象交给Spring容器来管理,使得很多复杂的代码在Spring开发中会变的简洁,有效的降低代码耦合度,极大的方便后期的维护、升级、拓展。

四种关键策略

  • 基于 POJO 的轻量级和最小侵入性编程
  • 通过依赖注入和面向接口实现松耦合
  • 基于切面和惯例进行声明式编程
  • 通过切面和模板减少样板式代码

特点

  • 非侵入式:基于 Spring 开发的应用中的对象可以不依赖于 Spring 的 API。
  • 容器:Spring 是一个容器,因为它包含并且管理应用对象的生命周期。
  • 控制反转:IOC (Inversion of Control),指的是将对象的创建权交给 Spring 去创建。
  • 使用 Spring 之前,对象的创建都是由我们自己在代码中 new 创建。而使用 Spring 之后。对象的创建都是由给了 Spring 框架
  • 依赖注入:DI (Dependency Injection),是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。
  • 面向切面编程:Aspect Oriented Programming——AOP。
  • 组件化:Spring 实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用 XML 和 Java 注解组合这些对象。
  • 一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库。

jar包下载

https://repo.spring.io/simple/libs-release-local/org/springframework/spring/

  • -dist 后缀表示该文件夹下存放的是 jar 包,文档和 xsd 文件;
  • -docs 后缀表示该文件夹下存放相关文档,开发指南和 API;
  • -schema 里存放了 Spring 所用的 xsd 文件。

Spring IOC容器

IOC思想

IOC (Inversion of Control) 是指在程序开发中,对象实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转。简单说就说Spring会完成对象创建,并将对象放入容器中

容器概念

IOC 容器就是具有依赖注入功能的容器,IOC 容器负责实例化、定位、配置应用程序中 的对象及建立这些对象间的依赖。应用程序无需直接在代码中 new 相关的对象,应用程序 由 IOC 容器进行组装。在 Spring 中 BeanFactory 是 IOC 容器的实际代表者。

Bean概念

在 Spring 中,被 Spring 容器所管理的对象称之为”Bean”对象。一个 Spring 的 Bean 对象可以是任何形式的 POJO。任何class类都可以视力恶化,并且class不用实现任何接口

容器类型

  • BeanFactory是基础类型的IOc容器,实例化对象和管理生命周期
  • ApplicationContext是BeanFactory的子接口,功能更强大

ApplicationContext有两个实现类

  • ClassPathXmlApplicationContext
    该类从类路径 ClassPath 中寻找指定的 XML 配置文件,找到并装载完成 ApplicationContext 的实例化工作
  • SystemXmlApplicationContext
    该类从指定的文件系统路径中寻找指定的 XML 配置文件,找到并装载完成 ApplicationContext 的实例化工作
两者区别

:在读取 Spring 的配置文件时,
FileSystemXmlApplicationContext 不再从类路径中读取配置文件,而是通过参数指定配置文 件的位置,它可以获取类路径之外的资源,如“F:/workspaces/applicationContext.xml”;

IOC容器使用

  • 需要导入相应jar包
  • 导入jar包之后需要相应的Spring配置文件,用于管理相应bean对象
  • 创建对应的接口和实现类,并通过修改配置文件,来管理其相应的对象
  • 通过启动IOC容器来获取相应.class的对象

jar包添加

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

  • Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称 为 Bean。
  • Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
  • Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
  • Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。是对JSP2.1 规范中规定的统一表达式语言(Unified EL)的扩展。
    以及Core需要依赖的日志包

添加Spring配置文件

文件名随意取,一般起名:applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd" >
               
  <bean id="usersService" class="com.bjsxt.service.impl.UsersServiceImpl"/>
</beans>               

创建接口和实现类

public interface UsersService {

    void addUsers();
}
public class UsersServiceImpl implements UsersService {     @Override 
public void addUsers() {
System.out.println("UsersService addUsers ......"); 
    }
}

获取IOC容器中的对象

public class UsersServiceTest { 
public static void main(String[] args) { 
/* UsersService usersService = new UsersServiceImpl(); usersService.addUsers();*/

//启动 Spring IOC 容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

//从 IOC 容器中获取 UsersService usersService = (UsersService) applicationContext.getBean("usersService"); usersService.addUsers(); 
}

这样我们就可以完成了对usersService对象的获取,我们使用IOC容器获取,而不是通过new的方式。

IOC容器创建Bean的三种方式

  • 通过构造方法
    实例化对象时,和正常new的时候一样,new的时候调用构造方法,从而完成实例化的过程
public class UsersServiceImpl implements UsersService { public UsersServiceImpl(){ System.out.println("Init......."); 
}
@Override 
public void addUsers() { 
System.out.println("UsersService addUsers ......"); 
}
}
  • 通过静态工厂方法创建对象
    静态工厂的话不需要频繁的创建对象
public class ObjectFactory { 
public static UsersService getInstance(){ 
return new UsersServiceImpl(); 
}
}
<!--    通过静态工厂方法实例化对象,加了factory-method不会实例化这个类ObjectFactory,而是根据你这个类的方法去实例化对象,创建出来之后会把对象放在IOC容器中-->
   <bean id="UsersService2" class="com.hhxx.factory.ObjectFactory" factory-method="getInstance"/>
  • 通过动态工厂方法创建对象
    由于是动态的,因此需要先实例化clsss,再由该对象调用其方法
public class DynamicObjectFactory { 
public UsersService getInstance(){ 
return new UsersServiceImpl(); 
} 
}
<!--通过动态工厂方法,实例化对象-->
<!--    先实例化DynamicObjectFactory,在通过第二个bean标签 factory-bean下的getInstance方法,并将对象存放容器中
和usersService3 唯一标识形成绑定 这样只需要获取这个id就能调取到相应对象-->
   <bean id="dynamicObjectFactory" class="com.hhxx.factory.DynamicObjectFactory"/>
    <bean id="usersService3" factory-bean="dynamicObjectFactory" factory-method="getInstance"/>

SpringIOC容器获取Bean对象方式

  • 通过id或name获取Bean对象
    applicationContext.getBean(id|name);
    name不能重复但是可以有多个
    配置文件
<bean id="usersService" name="name1,name2,name3" class="com.bjsxt.service.impl.UsersServicesImpl"  />
  • 通过类型获取Bean对象
    IOC容器中同一个类型的对象只能只有一个不能有多个,类型必须唯一的
    applicationContext.getBean(Class clazz);
UsersService usersService = applicationContext.getBean(UsersServiceImpl.class); usersService.addUsers();
  • 通过idhuoname与类型获取bean对象
    在 SpringIOC 容器中,通过类型获取对象时,如果同一类型存在多个对象,我们可以使用添加id 或 name 来识别需要获取的对象
    方式1:
UsersService usersService = applicationContext.getBean("name1",UsersServiceImpl.class); 
usersService.addUsers();

方式2
先获取到容器中所有的bean对象id,通过getBeanDefinitionNames()方法,返回所有bean对象id数组而不是name,通过索引来获得相应的具体对象

//获取 Spring IOC 容器中所有的 Bean 对象的 ID 
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); 
for(String name: beanDefinitionNames){ System.out.println(name); 
}
UsersService usersService = applicationContext.getBean(beanDefinitionNames[0],UsersServiceImp l.class); 
usersService.addUsers();

IOC容器创建对象的策略

Spring IOC 容器在启动时默认的会将在配置文件中所配置的所有 Bean 对象立即进行实 例化,并保存在IOC容器中。我们可以通过标签 lazy-init 属性的实现延迟实例化对象。
需要注意的是lazy init="false"scope作用域为singleton(单例,也是默认属性值)有效
容器创建对象可以分为:

  • 立即创建即默认的,在容器启动时会实例化文件中的所有bean对象
  • 延迟创建 lazy-int=“true” 在调用getbean方法时进行创建

Bean对象的作用域

作用域限定了 Spring Bean 的作用范围,在 Spring 配置文件定义 Bean 时,通过 声明 scope 配置项,可以灵活定义 Bean 的作用范围。

singleton(单例)

singleton 为 scope 属性的默认值。当 scope 属性的值为 singleton 时,Spring IOC 容器启 动时会立即实例化一次 Bean 对象,并一直被 Spring IOC 容器所缓存,所以生命周期较长。

  • singleton 特点:
    Spring IOC 容器启动时会创建 Bean 对象 也就是构造方法会调用
    每次调用 getBean 都返回 spring 容器中的唯一一个对象
<bean id="usersService" name="name1,name2,name3" class="com.bjsxt.service.impl.UsersServicesImpl" scope="singleton" />

prototype(多例)

lazy-init失效,是在getbean的时候进行实例化
当 scope 属性的值为 prototype 时,每次调用调用 getBean 方法时都会返回一个新的 Bean 对象,Spring IOC 容器并不会缓存该对象,所以就不再负责管理它的生命周期。

  • prototype 特点:
    Spring IOC 容器启动时不会创建 Bean 对象。
    每次调用 getBean 都会创建一个新 Bean 对象。
<bean id="usersService" name="name1,name2,name3" class="com.bjsxt.service.impl.UsersServicesImpl" scope="prototype"/>

单例和多例,底层其实对应的就是静态工厂和动态工厂

悲观者正确,乐观者成功
原文地址:https://www.cnblogs.com/freebule/p/13807143.html