1、Spring 基础系列之 IoC
2、Spring 基础系列之 Bean

IoC 控制反转

概念

以前是你需要做什么东西,是需要你自己去拿,现在是相当于有一个秘书,你说一下就有专门的人给你送过来,不需要亲自动手。

IoC的理念就是,让别人为你服务!

注入方式

构造方法注入
setter 方法注入
接口注入

三种注入方式的比较

1、接口注入
从使用上来说,不建议使用接口注入,因为接口注入需要强制实现不必要的接口,带有侵入性。

2、构造方法注入
这种方式的优点是,注入完成后就准备好了,可以马上使用了。
缺点就是依赖比较多的时候,构造方法的参数比较长。而且构造方法不能被继承,无法设置初始默认值。需要根据不同的业务情况,实现不通的构造方法,维护起来不方便。

3、setter方法注入
优点是通过命名可以直观的理解含义,可以被子类继承,设置默认值。
缺点是对象创建完后可能没有准备就绪,无法马上使用。


了解IoC的基本概念后,如何实现Ioc呢?
IoC Service Provider就是来实现这个功能的。有以下两个职责
1、完成对象的创建
在有了IoC之后无需手动去创建对象,IoC Service Provider会帮你完成相关的工作
2、管理对象之间的依赖关系
在需要完成某项业务时,需要依赖于其他的服务对象,IoC Service Provider会处理这些依赖的对象关系,在你调用这个服务之前注入依赖对象,保证业务使用前准备就绪。

IoC管理对接直接的依赖关系的方式包含以下几种:
1、编码方式
通过直接编码的方式,指定对象的依赖关系
2、配置文件方式
通过配置文件设置对象依赖关系
3、元数据方式
通过注解设置对象依赖关系

Spring IoC实现类型主要有两种BeanFactory和ApplicationContext
1、BeanFactory
Spring最基本的容器实现,包含了IoC的完整功能

2、ApplicationContext
高级容器实现,继承自BeanFactory,不仅包括了BeanFactory所有功能还包括其他高级特性(事件发布,国际化等)。

BeanFactory的对象关联依赖实现方式
1、编码方式

public static void main(String[] args) {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 //初始化bean定义
 RootBeanDefinition infoProvider = new RootBeanDefinition(StockInfoServiceImpl.class);
 RootBeanDefinition hqProvider = new RootBeanDefinition(StockHqServiceImpl.class);
 //向registry注册bean
 beanFactory.registerBeanDefinition("stockInfoService", infoProvider);
 beanFactory.registerBeanDefinition("stockHqService", hqProvider);
 //设置依赖关系
 //通过属性注入
 MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
 mutablePropertyValues.add("stockInfoService", infoProvider);
 hqProvider.setPropertyValues(mutablePropertyValues);
 //获取bean执行
 StockHqService stockHqService = beanFactory.getBean("stockHqService", StockHqService.class);
 StockHq hq = stockHqService.getHq(1, "601012");
}

BeanFactory只是一个接口,DefaultListableBeanFactory是BeanFactory的比较普通的实现类。不仅实现了BeanFactory接口还实现了BeanDefinitionRegistry接口(用于bean的注册管理)
image.png

2、配置文件方式(properties、xml)

properties配置文件方式

spring-hq.properties

stockInfoService.(class)=...StockInfoServiceImpl
stockHqService.(class)=...StockHqServiceImpl
#构造方式注入
#stockHqService.$0(ref)=stockInfoService
#set方式注入
stockHqService.stockInfoService(ref)=stockInfoService
/**
 * properties配置文件方式
 */
@Test
public void propertiesConfig() {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 PropertiesBeanDefinitionReader definitionReader = new PropertiesBeanDefinitionReader(beanFactory);
 definitionReader.loadBeanDefinitions("classpath:spring-hq.properties");
 //获取bean执行
 StockHqService stockHqService = beanFactory.getBean("stockHqService", StockHqService.class);
 StockHq hq = stockHqService.getHq(1, "601012");
 System.out.println(hq.toString());
}

xml配置文件方式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.springframework.org/schema/beans"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
 <bean id="stockInfoService" class="...StockInfoServiceImpl"></bean>
 <bean id="stockHqService" class="...StockHqServiceImpl">
 <constructor-arg index="0">
 <ref bean="stockInfoService"></ref>
 </constructor-arg> </bean></beans>
/**
 * xml配置文件方式
 */
@Test
public void xmlConfig() {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 XmlBeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(beanFactory);
 definitionReader.loadBeanDefinitions("classpath:spring-hq.xml");
 //获取bean执行
 StockHqService stockHqService = beanFactory.getBean("stockHqService", StockHqService.class);
 StockHq hq = stockHqService.getHq(1, "601012");
 System.out.println(hq.toString());
}

元数据方式
使用@Autowired、@Component等注解

/**
 * 元数据注解方式
 */
@Test
public void annotationConfig() {
    //加载配置了扫描路径的ApplicationContext
 //xml文件配置扫码路径<context:component-scan base-package="..." />
 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("配置文件路径");
 //获取bean执行
 StockHqService stockHqService = (StockHqService) applicationContext.getBean("stockHqService");
 StockHq hq = stockHqService.getHq(1, "601012");
 System.out.println(hq.toString());
}

lane
1 声望1 粉丝