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的注册管理)
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());
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。