spring IOC容器

原创
08/11 00:03
阅读数 40

Spring IOC容器

1、Spring 的BeanFactory容器

​ 这个是最简单的容器主要功能为DI(依赖注入) ,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义 ,在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。

实例:

Animal.java

package com.malajava.bean;

public class Animal {
    private String name;
    private String singing;

    public void getName() {
        System.out.print(name);
    }

    public void setName(String name) {
        this.name = name;
    }

    public void getSinging() {

        System.out.println(singing);

    }

    public void setSinging(String singing) {
        this.singing = singing;
    }
}

animal.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="cat" class="com.malajava.bean.Animal">
        <property name="name" value="小猫"/>
        <property name="singing" value="在唱歌"/>
    </bean>

</beans>

测试文件

package com.malajava.test;

import com.malajava.bean.Animal;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class AnimalTest {

    public static void main(String[] args) {
        String config = "classpath:animal.xml";
        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("animal.xml"));
        //XmlBeanFactory 主要负责创建并初始化对象

        Animal a = (Animal) factory.getBean("cat");
        //利用上面生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,
        // 该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法。
        a.getName();
        a.getSinging();
    }
}

2、Spring 的ApplicationContext容器

​ Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文。

3、Spring的Bean的定义

  • Bean的定义

    bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象 ,这些 bean 是由用容器提供的配置元数据创建的。

  • Bean与Spring容器之间的关系

​ 1、读取xml文件中的Bean配置信息传给Spring容器

​ 2、根据Bean的实现类利用Spring容器中的注册表信息实例化Bean

​ 3、将Bean实例放到Spring容器中(Bean缓存池)

​ 4、根据相关应用程序使用Bean

  • Spring配置元数据
    • 基于XML文件的配置文件(Spring1.x版本)
    • 基于注解配置(Spring2.x版本)
    • 基于Java配置(Spring3.x、Spring4.x)
实例:
<!-- A simple bean definition -->
   <bean id="..." class="...">
       <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- A bean definition with lazy init set on -->
   <bean id="..." class="..." lazy-init="true">
       <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- A bean definition with initialization method -->
   <bean id="..." class="..." init-method="...">
       <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- A bean definition with destruction method -->
   <bean id="..." class="..." destroy-method="...">
       <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- more bean definitions go here -->

4、Spring Bean的作用域

Spring 框架支持以下五个作用域,分别为singleton(无状态的Bean使用)、prototype(有状态的Bean使用)、request、session和global session。

作用域 描述
singleton 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
global-session 一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境

5、Bean的生命周期

当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。

为了定义安装和拆卸一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法。

Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁

实例:

HelloWorld.java

package com.malajava.bean;

public class HelloWorld {

    private String message;

    public void getMessage() {
        System.out.println(message);
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void init(){
        System.out.println("Bean 正在初始化……");
    }
    public void destroy(){
        System.out.println("Bean 正在销毁……");
    }

}

HelloTest.java

package com.malajava.test;

import com.malajava.bean.HelloWorld;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloTest {
    public static void main(String[] args) {
        String config = "classpath:helloworld.xml";
        ApplicationContext context = new ClassPathXmlApplicationContext(config);

        HelloWorld helloWorld = (HelloWorld) context.getBean("hello_1");

        helloWorld.getMessage();
        ((ClassPathXmlApplicationContext) context).registerShutdownHook();
        //你需要注册一个在 AbstractApplicationContext 类中声明的关闭 hook 的 registerShutdownHook() 方法。
        // 它将确保正常关闭,并且调用相关的 destroy 方法。

    }
}

helloworld.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="hello_1" class="com.malajava.bean.HelloWorld" init-method="init" destroy-method="destroy">
        <property name="message" value="Hello  World"/>
    </bean>

</beans>

6、Bean后置处理器

Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理。

BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现来完成实例化,配置和初始化一个bean之后实现一些自定义逻辑回调方法。

你可以配置多个 BeanPostProcessor 接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。

BeanPostProcessor 可以对 bean(或对象)实例进行操作,这意味着 Spring IoC 容器实例化一个 bean 实例,然后 BeanPostProcessor 接口进行它们的工作。

ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。

实例:

修改上方的helloworld.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="hello_1" class="com.malajava.bean.HelloWorld" init-method="init" destroy-method="destroy">
        <property name="message" value="Hello  World"/>
    </bean>

    <bean class="com.malajava.test.InitHelloWorld"/>

</beans>

InitHelloWorld.java

package com.malajava.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class InitHelloWorld implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("在初始化Bean之前"+beanName);

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化Bean之后执行"+beanName);
        return bean;
    }
}

7、Bean定义继承

  • 子 bean 的定义继承父定义的配置数据。子定义可以根据需要重写一些值,或者添加其他值。

  • Spring Bean 定义的继承与 Java 类的继承无关,但是继承的概念是一样的。你可以定义一个父 bean 的定义作为模板和其他子 bean 就可以从父 bean 中继承所需的配置.

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-3.0.xsd">

   <bean id="beanTeamplate" abstract="true">
      <property name="message1" value="Hello World!"/>
      <property name="message2" value="Hello Second World!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

   <bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="beanTeamplate">
      <property name="message1" value="Hello India!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

</beans>

父 bean 自身不能被实例化,因为它是不完整的,而且它也被明确地标记为抽象的。当一个定义是抽象的,它仅仅作为一个纯粹的模板 bean 定义来使用的,充当子定义的父定义使用。

展开阅读全文
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
在线直播报名
返回顶部
顶部