Spring IOC基础

Posted zhanghengbolg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring IOC基础相关的知识,希望对你有一定的参考价值。

1.1. Spring IOC 简介

 IOC(Inversion of Control)容器负责对象的创建,对象的存储,对象管理,核心功能就是控制反转。

2.1 Spring IOC 编程入门实现

  Spring IOC项目构建基本步骤:

  1. 创建maven 项目
  2. 添加spring 依赖(spring-context)及配置文件(spring-configs.xml)
    <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
    </dependency>

     

  3. 编写并配置java
  4. 编写单元测试初始化容器,获取java对象

3. Spring 框架组件IOC 基本应用

  3.1 Bean 对象的基本配置

    在软件应用中由Spring管理的所有对象都称之为Bean

    类的定义,符合如下规则的Java对象称为Bean

    1. 属性私有化
    2. 必须有无参构造器
    3. 必须实现 序列化接口
    4. 有getXXX setXXX 方法声明的"Bean属性

我们自己创建假如需要由spring管理,首先对这个类进行配置,常用配置方式有两种,一种基于xml进行配置,一种基于注解进行配置.

package beans;

public class HelloService {
    
    public HelloService() {
        System.out.println("HelloService created");
    }
    
}

基于xml方式对象Bean对象进行配置时,首先需要在spring的核心配置文件中使用bean标签对bean类型进行声明,借助id属性指定的bean的一个标识.通过class属性指定bean的具体类型(必须写全类名)

<bean id="helloService" class="beans.HelloService"></bean>
public class TestBeans01 {
    private ClassPathXmlApplicationContext applicationContext;
    @Before
    public void init(){
        //初始化spring-ioc容器
        applicationContext = new ClassPathXmlApplicationContext("spring-configs.xml");
    }
    @After
    public void destroy(){
        applicationContext.close();
    }
    
    @Test
    public void testSayHello(){
        HelloService helloService = applicationContext.getBean("helloService",HelloService.class);
     System.out.println(helloService); }

输出结果为:

技术分享图片

 

3.2 Bean 对象的构建方法

Spring 中Bean对象的构建,提供了如下几种方式:

 

1) 直接通过构造方法

 

2) 通过类的静态工厂方法(例如CalendargetInstance方法)

<bean id="calendar" class="java.util.Calendar" factory-method="getInstance"></bean>
    @Test
    public void testBeanGetMethod(){
        Calendar calendar = applicationContext.getBean("calendar", Calendar.class);
        System.out.println(calendar);
    }

3) 通过实例的实例方法构建对象(例如通过Calendar对象的getTime方法获取date对象).

<!-- Spring会调用calendar对象的getTime方法创建对象 -->
<bean id="date" class="java.util.Date" factory-bean="calendar" factory-method="getTime"></bean>
    @Test
    public void testBeanGetMethod(){
        Date date = applicationContext.getBean("date",Date.class);
        System.out.println(date);
    }

4) 通过工厂的实例方法

  1.声明一个要由工厂生产的类

package beans;

public class MyObject {
 
}

 

 

 

      2.创建工厂类,实现FactoryBean接口

public class ObjectFactory implements FactoryBean<MyObject>{

    public MyObject getObject() throws Exception {
        System.out.println("getObject()");
        return new MyObject();
    }
    /**
     * 此方法何时调用:
     *     1.创建新对象时
     *     2.容器关闭,isSingleton返回true时
     */
    public Class<?> getObjectType() {
        System.out.println("getObjectType()");
        return MyObject.class;
    }
  /**
   *返回true为单例
   *返回false为多例
   */
    public boolean isSingleton() {
        System.out.println("isSingleton()");
        return false;
    }

}

 

 

    3.在spring配置文件中配置bean

<bean id="objectFactory" class="beans.ObjectFactory"></bean>

    4.测试

    @Test
    /**
     * isSingleton返回true情况下输出:
     *        isSingleton()
     *        getObject()
     *        [email protected]
     *        [email protected]
     *        isSingleton()
     *        getObjectType()
     * isSingleton返回flase情况下输出:
     *        isSingleton()
     *        getObject()
     *        [email protected]
     *        isSingleton()
     *        getObject()
     *        [email protected]
     *        isSingleton()
     */
    public void testObjectFactory(){
        MyObject objectFactory1 = applicationContext.getBean("objectFactory",MyObject.class);
        System.out.println(objectFactory1);
        MyObject objectFactory2 = applicationContext.getBean("objectFactory",MyObject.class);
        System.out.println(objectFactory2);
    }
    

    5.把ObjectFactory交给spring管理确实能为我们生产MyObject对象,但是如果要获取ObjectFactory对象,需要在前面加上前缀"&"

    @Test
    public void testObjectFactoryBean(){
        ObjectFactory bean = applicationContext.getBean("&objectFactory", ObjectFactory.class);
        System.out.println(bean);
    }

3.3bean对象的作用域

在Spring容器中管理的Bean对象,可以在声明时通过scope属性或相关注解指定其作用域,最常用是singleton,prototype.其含义如下

1) singleton (这个作用域标识的对象具备全局唯一性):系统默认

2) prototype(这个作用域标识的对象每次获取都会创建新的对象)

     <bean id="helloService"
            class="beans.HelloService"
            scope="singleton"/>

3.4bean对象的生命周期

在Spring框架应用中,所有的的Bean对象都有生命周期,所谓Bean对象的生命周期是指Bean对象的创建,初始化,服务,销毁的这个过程.

在spring配置文件中可以通过Init-method,destory-method属性指定bean的生命周期方法.例如:

  <bean id="helloService"
            class="beans.HelloService"
            scope="prototype"
            init-method="init"
            destroy-method="destory"/>
  1. 单例对象 singleton(单例)

    • 创建: 在Spring容器初始化时候, 创建单例对象, 如果设置了init-method属性, 则在创建对象以后调用初始化方法.
    • 使用: 每次调用getBean时候, 返回的都是同一个对象
    • 销毁: 在Spring容器关闭时候,Spring会自动销毁单例对象, 如果指定了destroy-method属性, 则会在销毁之前执行 销毁 方法.
  2. 多例对象 prototype(原型)

    • 创建: 在调用getBean方法时候, 创建对象, 如果设置了init-method属性, 则在创建对象以后调用初始化方法.
    • 使用: 每次调用getBean时候, 返回的都是新对象
    • 销毁: Spring 不管!!! 也不会调用 destroy-method !!!

3.5bean对象的延迟加载

在spring框架应用,容器初始化时候,默认会构建所有由spring管理的Bean对象.但假如这些对象长时间不使用还占用着内存就会造成一定的资源浪费.为了解决这个问题,

spring中提供了一种延迟加载机制.通过这种机制来提高系统资源的有效使用.Spring中的延迟加载需要通过bean元素中lazy-init属性或beans元素的default-lazy-init="true"属性进行设置.

两者的不同点:

1) lazy-init: 应用在bean标签中用于指定这个bean的加载策略.

2) default-lazy-init:应用在beans标签中用于指定所有bean的加载策略.

<bean id="helloService"
            class="beans.HelloService"
            scope="singleton"
            lazy-init="true"/>

 


以上是关于Spring IOC基础的主要内容,如果未能解决你的问题,请参考以下文章

Spring基础:IOC概念引入

Spring基础:注解方式创建对象IOC

[死磕 Spring 17/43] --- IOC 之从单例缓存中获取单例 bean

spring学习--基础概念

死磕 Spring----- IOC 之从单例缓存中获取单例 bean

Spring -- IOC/DI 基础概念的理解