一、依赖对象注入的三种方式
①构造方法注入:特点是同一个对象不可能被注入两次,因此被注入对象的生命周期周期是由IOC进行管理,对象被构造完成就可以使用
②Setter注入:特点可在对象构造完成后再注入,扩展性比较强
③接口注入:需要被注入对象实现某个特定接口,这个接口提供一个注入对象的方法
对比:①使用构造方法注入在对象构造完成时,即处于可用状态,但是当依赖对象过多时,构造方法参数列表会比较长②Setter注入当对象构造完成后无法马上进入就绪状态③接口注入需要实现多余的接口,侵入性比较强【目前很少用】
二、Ioc Service Provider
Ioc Service Provider职责:业务对象构建管理【即创造对象】和业务对象间的业务绑定【即引用对象】
管理对象间依赖的方式:直接编码方式、配置文件方式、注解方式(特殊的编码方式)
三、Srping的Ioc容器——BeanFactory和ApplicationContext
Spring提供两种容器类型:BeanFactory和ApplicationContext
①BeanFactory:基础类型Ioc容器,采用延迟初始化策略【当需要访问容器某个受管的对象时,才对对象进行初始化和依赖操作】,所以容器初始化较快,所需资源较少。对于资源有限,且功能要求不是很严格可以考虑使用BeanFactory容器。【虽然是基础类型容器,但是可以完成Ioc Service Provider职责,创造和引用对象】
②ApplicationContext在BeanFactory基础上构建,是一种高级容器,除了拥有BeanFactory所有支持,还提供事件发布、国际化信息等功能。该容器启动后,默认初始化并绑定完成,所以ApplicationContext相对BeanFactrory会需要等多资源及等待时间更长。下面是ApplicationContext类图【Idea快捷键:Ctrl+Shift+Alt+U显示类图】,可以看出ApplicationContext间接继承自BeanFactory,除此之外还继承其它三个接口【之后会讲到】
四、BeanFactory对象注册和依赖绑定方式
首先详细介绍一下BeanFactory使用:
BeanFactory只是一个接口【访问查询Bean】,DefaultListableBeanFactory则是一个比较通用的接口实现类,此外它还实现了BeanDefinitionRegistry接口,该接口才是BeanFactory中担当Bean注册管理角色。他们的类图如下【摘自网络】
直接编码方式:
public class SpringTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
registerBean(beanFactory, "example", new RootBeanDefinition(Example.class));
Example example = beanFactory.getBean("example", Example.class);
example.sayHello("Tom");//just say hello
}
/**
* @param beanFactory
* @param beanName
* @param bean
*/
public static void registerBean(DefaultListableBeanFactory beanFactory, String beanName, AbstractBeanDefinition bean) {
beanFactory.registerBeanDefinition(beanName, bean);
}
}
外部配置文件方式:
//xml加载
DefaultListableBeanFactory beanFactory1=new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader=new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("资源文件路径");
// Properties加载
DefaultListableBeanFactory beanFactory2=new DefaultListableBeanFactory();
PropertiesBeanDefinitionReader propertiesBeanDefinitionReader=new PropertiesBeanDefinitionReader(beanFactory2);
propertiesBeanDefinitionReader.loadBeanDefinitions("资源文件路径");
注解方式:
<context:component-scan base-package="需要被扫描包的路径"/>
@compent
@Service
@Autowired