Spring的IOC該如何理解呢?
平常在一個方法當中,若要用到外部另一個類裏的非靜態方法,首先,需要先通過new一個對象,再根據這個對象去調用其方法。若只需要一兩個對象還好,一旦涉及的外部對象多了,就要創建一大堆new,管理起來就很麻煩。這時候,IOC的思想就起到關鍵作用了,它可以實現把創對象創建與操作統一交給框架管理。那麼,新創建的對象都是怎麼存在spring框架當中的呢?其實,這裏面就用到了Map緩存。你可以簡單這樣理解,spring就像一個map容器,bean都存放在這個map裏,若要用到map裏存放的對象,就可以通過一個key去map裏獲取,這個key,可以是id或者bean的默認名。
以後,若要用到這個對象,例如spring最簡單的如註解方式——
@Resource
private DemoService demoService;
如此定義之後,Spring框架就會幫我們自動創建一個DemoService單例對象,然後將demoService引用指向對象的地址,接下來,就可以直接通過引用demoService變量調用DemoService裏的方法了。至於Spring如何通過註解方式來實現調用Bean對象的,後面會專門寫一篇文章介紹。
Spring給我們提供兩種類型的IoC容器實現,通過這兩種IOC容易,可以生成bean,並獲取bean:
- 實現了BeanFactory接口的基本IoC容器。
- 實現了ApplicationContext接口的高級IoC容器。
實現BeanFactory接口的基本IoC容器一般如下:
@Test
public void createWithNullTarget() {
Resource resource = new ClassPathResource("myBean.xml");
// 構造工廠
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 新增Xml閱讀器
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// 規則註冊入容器
reader.loadBeanDefinitions(resource);
Pet person = factory.getBean(Pet.class);
System.out.println(person.toString());
}
實現了ApplicationContext接口的高級IoC容器一般如下:
XXXServiceImpl XXXService = SpringContextUtils.getBean(XXXServiceImpl.class);
再封裝SpringContextUtils工具——
@Component
public class SpringContextUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
}
實際應用當中,多是使用ApplicationContext接口的高級IoC容器來獲取Spring管理的bean。