Spring学习2:IOC(控制反转)和容器

Spring IOC容器

IOC(控制反转)容器:

  • Spring容器是Spring框架中的一个核心组件,容器将创建对象,把它们联系在一起并配置它们,管理它们的整个生命周期从创建到销毁。IOC容器是具有依赖注入功能的容器,它可以创建对象,并负责对对象进行实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。平时我们new一个新的实例,控制权在我们程序员的手里,而“控制翻转”就是指的是new的实例工作不再由程序员来做,而是交给Spring容器来做,这一节学习我们就来学习Spring的容器~

spring容器

一、Spring BeanFactory容器

1、描述

  • Spring BeanFactory 容器,它是最简单的容器,给 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware ,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。
  • 在Spring中,有大量对BeanFactory接口的实现,最常使用的是XmlBeanFactory类。该容器从XML文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用程序。

2、Spring BeanFactory的使用

  • 第一步:创建一个名为 SpringExample 的工程并在 src 文件夹下新建一个名为 studio_day1 的包,在与src文件同层次的文件路径中新建一个lib文件夹。
  • 第二步:把Spring的所有相关jar包导入到lib文件夹中,然后右键,选择 Add External JARs 选项,导入 Spring 的库文件。
  • 第三步:在studio_day1下新建名为HelloWorld的class和名为Main的class。
  • 第四步:在src文件下创建Bean的配置文件Spring-conf.xml
  • 第五步:开始配置Bean文件。

HelloWorld.java文件内容:

package studio_day_1;

public class HelloWorld {

    private String name;

    public String getName() {
        return name;
    }

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

    public void sayhello(){
        System.out.println("hello !"+ name);
    }
}

Main.java文件的内容:

package studio_day_1;


import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;

public class Main {
    public static void main(String[] args) {
        //创建一个spring ioc容器
        XmlBeanFactory context=new XmlBeanFactory(new ClassPathResource("spring-conf.xml"));
        //FileSystemXmlApplicationContext 必须使用绝对地址 否则会找不到xml文件
        HelloWorld helloWorld=(HelloWorld) context.getBean("helloworld");
        helloWorld.sayhello();
    }
}

Main函数中,我们使用的时候需要注意:

  • 第一步利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 bean
  • 第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法,相当于new了一个新对象,可以调用该类的所有公共函数和共有属性。

spring-conf.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="helloworld" class="studio_day_1.HelloWorld">
        <property name="name" value="Spring!"/>
    </bean>
</beans>

注意:在xml配置文件中,bean id不能重复,class必须是类的包名+类名。
如果所有配置都成功,运行结果如下:
在这里插入图片描述

二、Spring ApplicationContext容器

Spring ApplicationContext 容器

  • Application Context 是 BeanFactory 的子接口,也被成为 Spring 上下文。
  • Application Context 是 spring 中较高级的容器。和 BeanFactory 类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。 另外,它增加了企业所需要的功能,比如,从属性文件中解析文本信息和将事件传递给所指定的监听器。这个容器在 org.springframework.context.ApplicationContext interface 接口中定义。
  • ApplicationContext 包含 BeanFactory 所有的功能,一般情况下,相对于 BeanFactory,ApplicationContext 会更加优秀。当然,BeanFactory 仍可以在轻量级应用中使用,比如移动设备或者基于 applet 的应用程序。
  • 最常使用的ApplicationContext接口实现:
    • FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
    • ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
    • WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。

接下来我们测试Spring ApplicationContext容器:
构建过程和Spring BeanFactory容器类似,这里就不赘述。
HelloWorld.java文件内容:

package studio_day_1;

public class HelloWorld {

    private String name;

    public String getName() {
        return name;
    }

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

    public void sayhello(){
        System.out.println("hello !"+ name);
    }
}

Main.java文件内容:

package studio_day_1;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        //创建一个spring ioc容器
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-conf.xml");
        ApplicationContext context1=
                new FileSystemXmlApplicationContext("C:\\Users\\ouguangji\\Desktop\\Envs\\spring_stdio_1\\src\\spring-conf.xml");
        //FileSystemXmlApplicationContext 必须使用绝对地址 否则会找不到xml文件
        HelloWorld helloWorld=(HelloWorld) context.getBean("helloworld");
        HelloWorld helloWorld1=(HelloWorld) context1.getBean("helloworld");
        helloWorld.sayhello();
        helloWorld1.sayhello();
    }
}

由上可以得到使用ClassPathXmlApplicationContext,可以直接使用xml文件,不需要绝对路径就可以进行使用,但是在使用FileSystemXmlApplicationContext的时候,必须把xml文件写入绝对路径才可以正常运行。

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="helloworld" class="studio_day_1.HelloWorld">
        <property name="name" value="Spring!"/>
    </bean>
</beans>

三、Spring Bean后置处理器

Spring——Bean 后置处理器 描述:

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

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

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

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

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

实现步骤如下:

步骤 描述
1 创建一个名称为 SpringExample 的项目,并且在创建项目的 src 文件夹中创建一个包 com.tutorialspoint。
2 使用 Add External JARs 选项,添加所需的 Spring 库。
3 在 包中创建 Java 类 HelloWorld、InitHelloWorld 和 MainApp。
4 在 src 文件夹中创建 Beans 配置文件 spring-conf.xml。
5 最后一步是创建的所有 Java 文件和 Bean 配置文件的内容,并运行应用程序,解释如下所示。

这里是 HelloWorld.java 文件的内容:

package studio_day_1;

public class HelloWorld {
    private String message;
    public void setMessage(String message){
        this.message  = message;
    }
    public void getMessage(){
        System.out.println("Your Message : " + message);
    }
    public void init(){
        System.out.println("Bean is going through init.");
    }
    public void destroy(){
        System.out.println("Bean will destroy now.");
    }
}

这是InitHelloWorld.java文件内容:

  • 这是实现 BeanPostProcessor 的非常简单的例子,它在任何 bean 的初始化的之前和之后输入该 bean 的名称。你可以在初始化 bean 的之前和之后实现更复杂的逻辑,因为你有两个访问内置 bean 对象的后置处理程序的方法。
package studio_day_1;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;
public class InitHelloWorld implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeforeInitialization : " + beanName);
        return bean;  // you can return any other object as well
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("AfterInitialization : " + beanName);
        return bean;  // you can return any other object as well
    }
}

这是Main.java文件内容:

package studio_day_1;


import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Main {
    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-conf.xml");
        HelloWorld obj = (HelloWorld) context.getBean("helloworld");
        obj.getMessage();
        context.registerShutdownHook();
    }
}

这是spring-conf.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="helloworld" class="studio_day_1.HelloWorld"
    init-method="init" destroy-method="destroy">
        <property name="message" value="Hello World!"/>
    </bean>

    <bean class="studio_day_1.InitHelloWorld"/>
</beans>

配置完毕运行结果如下:
在这里插入图片描述
根据这个Spring Bean后置器的机制,我们就可以很方便的在该对象创建前和创建后进行某种操作,在开发过程中能更加的灵活多变。

发布了65 篇原创文章 · 获赞 29 · 访问量 6498

猜你喜欢

转载自blog.csdn.net/qq_41617848/article/details/104211240