Spring IoC讲解

大家好,我是一个爱举铁的程序员Shr

 

本文介绍Spring框架实现控制反转(Inversion of Control)的原理。阅读本篇文章可能需要6分钟。

 

IoC中最基本的就是反射,如果有读者不了解反射,可以参考我之前写过的一篇文章。

 

IoC使用的是工厂模式。

 

先讲几个概念。

 

一、控制反转

先来看一段代码。

public class StudentServiceImpl {
    private StudentDao studentDao = new StudentDaoImpl();

    /**
     * 查找所有学生
     * @return
     */
    public List<Student> getStudentList(){
        List<Student> studentList = studentDao.getStudentList();
        return studentList;
    }
}


StudentDaoImpl是在程序中创建的,而控制反转就是将对象的创建和维护都交给容器来管理。

 

二、依赖注入

基于构造方法注入,上面的代码可以改成下面这样:

public class StudentService {
    private StudentDao studentDao;

    // 构造方法注入
    public StudentService(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    /**
     * 查找所有学生
     * @return
     */
    public List<Student> getStudentList(){
        List<Student> studentList = studentDao.getStudentList();
        return studentList;
    }
}


基于Setter方法注入,可以改成这样:

public class StudentService {
    private StudentDao studentDao;

    // Setter方法注入
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    /**
     * 查找所有学生
     * @return
     */
    public List<Student> getStudentList(){
        List<Student> studentList = studentDao.getStudentList();
        return studentList;
    }
}


容器在创建对象时注入依赖的对象的值。

 

三、容器

接口org.springframework.beans.factory.BeanFactory称为Bean容器。

 

接口org.springframework.contex.ApplicationContext称为应用上下文它是BeanFactory的子接口

 

容器通过读取配置元数据获取关于实例化、配置和组装对象的指令。配置元数据用XMLJava注释或Java代码表示。

 

ApplicationContext有多个实现类,常用的有

ClassPathXmlApplicationContext ,读取classpath中的资源

FileSystemXmlApplicationContext,读取硬盘指定路径的文件资源

XmlWebApplicationContext,读取Web应用程序中的资源

 

3.1 基于XML配置容器的元数据

通常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="studentDao" class="com.shrmus.spring.ioc.dao.StudentDao">
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

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


id属性用来标识单个bean定义的字符串,class属性是类的全限定名。

 

编写一个测试类:

public class StudentTest {
    @Test
    public void test01() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        StudentDao studentDao = (StudentDao) applicationContext.getBean("studentDao");
        List<Student> studentList = studentDao.getStudentList();
        System.out.println(studentList);
        // 输出 [Student [id=1, name=张三, age=20, gender=1], Student [id=3, name=33, age=333, gender=3333]]
    }
}


FileSystemXmlApplicationContextXmlWebApplicationContext读者可以自己测试。

 

3.2 基于注解的方式注入

首先需要在applicationContext.xml中引入context命名空间。

 

applicationContext.xml中添加context:component-scan标签。如:

<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">    

    <!-- 设置自动扫描包和扫描bean,扫描包和子包下的类,多个包用逗号隔开 -->
    <context:component-scan base-package="com.shrmus.spring.ioc"></context:component-scan>
</beans>
 
 


几个常用的注解有@Repository@Service@Controller,分别用于数据访问层,业务层,控制层,另外还有@Component

 

3.3 Bean的作用域

通过bean标签的scope属性来设置bean的作用域,默认是singleton,单例(饿汉式),我们可以指定bean标签的lazy-init=true来设置成懒汉式。

 

另外scope属性还有prototyperequestsessionsessionglobalSessionapplicationwebsocket

 

设置成prototype每次获取的都是新创建的对象。

 

其他的属性值的意思可以查看官方文档了解。

https://docs.spring.io/spring/docs/4.3.17.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-scopes

 

关于更多的Bean的介绍,可以参考https://docs.spring.io/spring/docs/4.3.17.RELEASE/spring-framework-reference/htmlsingle/#beans-definition

中的表7.1

 

总结

挺久没写文章了,有点生疏,有的知识点可能没有写到。

 

在使用Spring的时候Spring配置文件中的命名空间都是复制来的,可能不知道是什么意思,今天这篇文章只讲了一下context命名空间,还有aoptx等命名空间,在后面的文章中将会介绍。

 

已经很晚了,睡觉。


猜你喜欢

转载自blog.csdn.net/ShrMuscles/article/details/80892474