关于spring:Spring-学习笔记二SpringIoC

51次阅读

共计 2824 个字符,预计需要花费 8 分钟才能阅读完成。

1 IoCDI

IoCInversion of Control 的简称,也就是管制反转。通常来说,创建对象须要调用者手动创立,也就是 new XXX() 的形式。当 Spring 框架呈现后,对象的实例不再由调用者创立,而是由 Spring 容器创立,这样控制权就由调用者转移到 Spring 容器,控制权产生了反转,这就是 Spring 的管制反转。从 Spring 容器来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它所依赖的实例,这就是 Spring 的依赖注入(Dependency InjectionDI)。

一句话总结:

  • IoC:控制权由调用者交由 Spring 容器,管制产生了反转
  • DI:由 Spring 容器注入须要的值到对象中

2 Spring IoC容器

Spring中实现 IoC 的是 Spring IoC 容器,次要基于以下两个接口:

  • BeanFactory
  • ApplicationContext

2.1 BeanFactory

位于 org.springframework.beans.factory 下,提供了残缺的 IoC 服务反对,是一个治理 Bean 工厂,次要负责初始化各种 Bean。能够通过XmlBeanFactory 来获取 XML 文件中的 Bean 并进行拆卸,例子如下:

BeanFactory factory = new XmlBeanFactory(new FileSystemResource("/xxx/xxx/xxx/xxx/applicationContext.xml"));
TestInterface test = (TestInterface)factory.getBean("test");
test.hello();

须要应用绝对路径,而且,该办法曾经过期了:

因而不举荐应用。

2.2 ApplicationContext

ApplicationContextBeanFactory 的子接口,也称为利用上下文,除了蕴含 BeanFactory 的性能外还增加了国际化、资源拜访、事件流传等的反对,创立 ApplicationContext 的实例有以下三种办法:

  • ClassPathXmlApplicationContext
  • FileSystemXmlApplicationContext
  • Web服务器实例化

2.2.1 ClassPathXmlApplicationContext

该类从 resources 下寻找指定的 XML 文件:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
TestInterface test = (TestInterface)context.getBean("test");
test.hello();

2.2.2 FileSystemXmlApplicationContext

该类读取配置文件须要加上前缀:

  • classpath::该前缀示意从类门路读取,对于 Maven 我的项目来说就是resources
  • file::该前缀示意从绝对路径获取

例子:

ApplicationContext context = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
//ApplicationContext context = new FileSystemXmlApplicationContext("file:/xxx/xxx/xxx/xxxx/xxx/applicationContext.xml");

2.2.3 Web服务器实例化

个别应用基于 ContextLoaderListener 的实现形式,批改web.xml,增加如下代码:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
</context-param>

3 DI的两种办法

DI通常有两种实现形式:

  • 构造方法注入
  • setter注入

上面别离来看一下。

3.1 构造方法注入

Spring能够利用反射机制通过构造方法实现注入,比方有以下三个类:

public interface TestInterface {void hello();
}

public class TestA implements TestInterface {
    @Override
    public void hello() {System.out.println("Test A");
    }
}

public class TestB {
    private TestInterface test;

    public TestB(TestInterface test)
    {this.test = test;}

    public void method()
    {test.hello();
    }
}

TestInterface是一个简略的接口,而 TestA 实现了该接口,TestB须要一个 TestInterface 类型的对象,因而能够先注入一个 TestA,再将该TestA 注入到 TestB 的构造方法中:

<bean id="testA" class="TestA"/> <!-- 注入一个 TestA 对象 -->
<bean id="testB" class="TestB">
    <constructor-arg index="0" ref="testA" /> <!-- 将下面注入的 TestA 作为参数传入构造方法中,在传给 TestB 的公有成员 -->
</bean>

constructor-arg是用于定义通过构造方法的形式进行注入的标签,index定义地位,从 0 开始,ref是某个 Bean 的援用,值为该 Beanid

3.2 通过 setter 注入

在下面的例子中,批改 TestB 如下:

public class TestB {
    private TestInterface test;

    public void setTest(TestInterface test) {this.test = test;}

    public void method()
    {test.hello();
    }
}

其实就是增加了一个setter,接着批改配置文件:

<bean id="testA" class="TestA"/>
<bean id="testB" class="TestB">
    <property name="test" ref="testA" />
</bean>

<property>示意通过 setter 注入,name是公有成员的名字,ref是被传入 setterBeanid 值。

正文完
 0