您的位置:首页 > 编程语言 > Java开发

Spring IOC容器实现

2016-06-22 22:16 537 查看
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;
}
}


           
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息