1、IOC容器与控制反转
Ioc容器是Spring实现控制反转的平台,通过使用Ioc容器,对象依赖关系的管理被反转了,转到IOC容器中了,对象之间的相互依赖关系由Ioc容器进行管理,并由Ioc容器完成对象的注入。
Spring Ioc提供了一个基本的JavaBean容器,通过Ioc模式管理依赖关系,并通过依赖注入和AOP切面增强了为JavaBean这样的POJO对象赋予事务管理、生命周期管理等基本功能。
在Spring的Ioc设计中,setter注入和构造器注入是主要的注入方式,相对而言,使用Spring时setter注入是常用的注入方式。
2、Ioc容器设计
在Spring容器的设计中,包含了两个容器系列,一个是实现BeanFactory接口的简单容器系列,实现了容器的最基本功能;另一个是实现ApplicationContxt应用上下文,作为容器的高级实现形式存在。
Spring容器继承体系:
- BeanFactory容器设计
1)
BeanFactory接口定义
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; //getBean是IoC容器中最重要的方法,通过该方法可以取得IoC容器中管理的Bean,Bean的取得是通过指定名字来进行所引的。 <T> T getBean(String name, Class<T> requiredType) throws BeansException; //根据指定的名字和类型取得IoC容器中管理的Bean,和getBean(String name)方法类似,只是多提供了一个类型安全验证机制。 <T> T getBean(Class<T> requiredType) throws BeansException; //根据指定的类型取得IoC容器中管理的Bean,该方法根据指定的类型调用ListableBeanFactory(BeanFactory下的)中的取得Bean方法,但是也可能根据给定的类型调用通过名字取得Bean的方法。 Object getBean(String name, Object... args) throws BeansException; //该方法重载了getBean(String name)方法,可变参数主要用来指定是否显示使用静态工厂方法创建一个原型(prototype)Bean。 <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; boolean containsBean(String name); //该方法让用户判断IoC容器中是否含有指定名字的Bean。 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //该方法用来查询指定名字的Bean是否是单态类型(singleton)的Bean。 boolean isPrototype(String name) throws NoSuchBeanDefinitionException; //该方法用来查询指定名字的Bean是否是原型(prototype)类型的Bean。 boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; //该方法用来查询指定名字的Bean的class类型是否支持特定的class类型。 Class<?> getType(String name) throws NoSuchBeanDefinitionException; //该方法用来查询指定名字的Bean的class类型。 String[] getAliases(String name); //该方法用来查询指定名字的Bean的所有别名。 }
2)
BeanFactory简单容器的设计实现
XmlBeanFactory是Ioc容器系列里面,一个简单的Ioc容器,它只提供最基本的IoC容器功能。
XmlBeanFactory源码:
public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); /** * Create a new XmlBeanFactory with the given resource, * which must be parsable using DOM. * @param resource XML resource to load bean definitions from * @throws BeansException in case of loading or parsing errors */ public XmlBeanFactory(Resource resource) throws BeansException { this(resource, null); } /** * Create a new XmlBeanFactory with the given input stream, * which must be parsable using DOM. * @param resource XML resource to load bean definitions from * @param parentBeanFactory parent bean factory * @throws BeansException in case of loading or parsing errors */ public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); } } XmlBeanFactory继承自DefaultListableBeanFactory,DefaultListableBeanFactory是一个重要的IOC容器实现,XmlBeanFactory是对DefaultListableBeanFactory的封装实现。根据包装,可以看到DefaultListableBeanFactory 容器的使用过程如下; //创建IoC容器管理的Bean的xml配置文件,即定位资源 ClassPathResource resource = new ClassPathResource(“beans.xml”); //创建BeanFactory DefaultListableBeanFactory factory = new DefaultListableBeanFactory (); //创键Bean定义读取器 XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); //使用Bean定义读取器读入Bean配置信息,即载入配置 reader.loadBeanDefinitions(resource);
- ApplicationContext容器设计
1)
ApplicationContext接口
ApplicationContext是高级形态的Ioc容器,它实现了BeanFactory,除了提供前面简单容器的基本功能外,还附加了很多服务功能。包括:
- 1)支持不同的信息源。通过扩展MessageSource接口,扩展可以支持3国际化,为开发多语言应用服务。
- 2)访问资源。通过实现ResourceLoader接口,提供从不同地方获取Bean定义资源。
- 3)支持应用事件。通过继承ApplicationEventPublisher接口,从而在上下文中引入了事件机制。
2)ApplicationContext容器的设计实现
ApplicationContext容器典型、常用的实现有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext。
FileSystemXmlApplicationContext主要功能在
AbstractXmlApplicationContext中已经实现,FileSystemXmlApplicationContext主要实现两个功能:
1)实例化FileSystemXmlApplicationContext时,启动容器refresh()过程,完成启动容器的一系列复杂操作。
2)完成Bean定义资源的获取定位。
源码:
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext { public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } } @Override protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); } }
可以看到在
AbstractRefreshableApplicationContext继承自AbstractApplicationContext,定义了
DefaultListableBeanFactory 类型的
beanFactory成员,通过关联DefaultListableBeanFactory 简单容器,实现容器的基本功能。并且在AbstractApplicationContext类中实现了BeanFactory接口中的所有方法,通过
getBeanFactory()方法获取beanFactory,并将容器基本操作委派给beanFactory简单容器。
在AbstractApplicationContext中:
@Override public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException; @Override public assertBeanFactoryActive(); return } @Overridepublic assertBeanFactoryActive(); return } @Overridepublic assertBeanFactoryActive(); return } @Overridepublic assertBeanFactoryActive(); return } @Overridepublic boolean return getBeanFactory().containsBean(name); } @Overridepublic boolean assertBeanFactoryActive(); return } @Overridepublic boolean assertBeanFactoryActive(); return }
在 AbstractRefreshableApplicationContext中:
/** Bean factory for this context */ private DefaultListableBeanFactory beanFactory; @Override public final synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return this.beanFactory; } }