AppFuse1.8中IOC的使用.

1What is IoC
IoC
设计模式-重点关注的是组件之间的依赖性、配置以及生命周期
以前我们在做代码使用实例之前必须创建对象的实例,但是IoC将创建对象的实例的任务由IoC容器或框架来完成,应用代码能直接使用对象.这就是IoC

2
.使用IoC的好处
       
组件(类,代码)不需要在运行的时候寻找依赖对象,借助与设值方法能够在允许是将组件以来的其他组件注入进来,这就是依赖注入(Dependency
Injection

       
借助IoC容器的组件依赖关系,测试将更加便利。在AppFuse在开发过程中使用Drive Test能很好的体现出来。
       
体现了Spring的非入侵性,即很少需要使用具体IoC容器提供的API

AppFuse
中使用IoC的地方

BeanFactory提供了管理和操作JavaBean的基本功能,Bean的生命周期可分为四个阶段

1.  Instantiation JavaBean

2.  Initialize JavaBean,通过IoC注入其依赖性

3.  Using JavaBean

4.  Destroy Bean

 

 

ApplicationContext

       ApplicationContext继承了BeanFactory, 含有BeanFactory的全部功能,通过ContextLoaderServletContextLoaderListener能够自动创建ApplicationContext实例。应此AppFuse也是使用ApplicationContext的。

       对于Spring  ApplicationContext而言ContextLoaderListenerContextLoaderServlet初始化完成后,所有的Bean实例将会被创建。除非你改掉他的默认设置

       ApplicationContext接口实现经常用到的是ClassPathXmlApplicationContext(装载配置文件,单元测试)FileSystemXmlApplicationContext(从文件系统钟装载配置文件,单元测试)

XmlWebApplicationContext(供ContextLoaderListenerContextLoaderServlet内部装载Spring配置文件使用)

 

AppFuse中的ApplicationContext

       AppFuse中的ApplicationContext加载是通过ContextLoaderListener配置实现的,但是AppFuse不是直接在web.xml配置ContextLoaderListener监听器来实现ApplicationContext的初始化的,而是通过自定义的StartupListener监听器实现配置的。

 

 

 

 

 

 

 

 

ApplicationContextWeb.xml中的配置

<!—

Context Configuration locations for Spring XML files

 -->

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>

            classpath*:META-INF/applicationContext-*.xml

            /WEB-INF/applicationContext-*.xml

        </param-value>

</context-param>

 

所有与applicationContext-*.xml的(*)匹配的都是Spring的配置文件,比如appicationContext-service.xml , applicationContext-hibernate.xml

applicationContext-security.xml

ApplicationContext的初始化

StartupListener 监听器继承了ContextLoaderListener监听器 ServletContextListener监听器。

Ø Web容器启动时,执行StartupListener监听器

Ø StartupListener监听器执行父类ServletContextListenercontextInitialized事件,在该初始化事件中,会调用SpringcontextInitialized事件初始化SpringApplicationContext

public class StartupListener extends ContextLoaderListener implements ServletContextListener {

   

    private static final Log log = LogFactory.getLog(StartupListener.class);

 

    public void contextInitialized(ServletContextEvent event) {

        if (log.isDebugEnabled()) {

            log.debug("initializing context...");

        }

 

        // call Spring's context ContextLoaderListener to initialize

        // all the context files specified in web.xml

        super.contextInitialized(event);

       

        //容器启动时,自动调用contextInitialized函数。

        //取得全局Application Scope 上下文环境

        ServletContext context = event.getServletContext();

        String daoType = context.getInitParameter(Constants.DAO_TYPE);

 

        // if daoType is not specified, use DAO as default

        if (daoType == null) {

            log.warn("No 'daoType' context carameter, using hibernate");

            daoType = Constants.DAO_TYPE_HIBERNATE;

        }

 

        // Orion starts Servlets before Listeners, so check if the config

        // object already exists

        Map config = (HashMap) context.getAttribute(Constants.CONFIG);

 

        if (config == null) {

            config = new HashMap();

        }

 

        // Create a config object to hold all the app config values

        //DAO_TYPE_HIBERNATE = "hibernate"写入ServletContext

        config.put(Constants.DAO_TYPE, daoType);

        context.setAttribute(Constants.CONFIG, config);

 

        // output the retrieved values for the Init and Context Parameters

        if (log.isDebugEnabled()) {

            log.debug("daoType: " + daoType);

            log.debug("populating drop-downs...");

        }

        //调用setupContext(context)函数初始化Spring

        setupContext(context);

    }

 /**

  * 初始化Spring环境上下文,为getBean作准备,并且将ServletContext交给Spring管理

  */

    public static void setupContext(ServletContext context) {

        ApplicationContext ctx =

            WebApplicationContextUtils.getRequiredWebApplicationContext(context);

       

        //通过Ico反射注入,查找lookupManagerDao属性

        LookupManager mgr = (LookupManager) ctx.getBean("lookupManager"); //Note 1:

 

        // get list of possible roles

        //取得角色信息,存入ServletContext scope中。

        context.setAttribute(Constants.AVAILABLE_ROLES, mgr.getAllRoles());

 

        if (log.isDebugEnabled()) {

            log.debug("drop-down initialization complete [OK]");

        }

    }

}

 

 

 

 

Note 1

从这句代码 LookupManager mgr = (LookupManager) ctx.getBean("lookupManager"); 体验一下AppFuse中用到Spring的面向接口编程,这个是Spring的一个特点-自然的面向接口编程。

我们知道AppFuse中代码职责分明,(dao ,service ,web

LookupManagerImpl Service 层的。用来管理POJO ,真正的数据操作委派给它引用的lookupDAO

的具体实现类 LookupDAOHibernate

AppFuseSpring配置文件 applicationContext-service.xml

<bean id="lookupManager" class="net.smarthings.service.impl.LookupManagerImpl">

        <property name="lookupDAO" ref="lookupDAO"/>

</bean>

 

<property name="lookupDAO" ref="lookupDAO"/>

先看前半句<property name="lookupDAO" 说明 Class LookupManagerImpl 中有一个给lookupDAO设置属性的方法setLookupDAO 注意改方法前面的set 如果是setSonic(Sonic son)的话,就应改这样设置<property name="sonic"

Class LookupManagerImpl 中有这么一个方法

public void setLookupDAO(LookupDAO dao) {

       //Spring动态注入了dao引用,从配置文件中得到了具体的lookupDAO接口对象

    this.dao = dao;

}

 

再看看后半句。ref="lookupDAO" 引用了LookupDAOHibernate的对象 <bean id="lookupDAO" 也可以这么说:通过IOC动态加载了对象属性LookupDAOHibernate

AppFuseSpring配置文件 applicationContext-hibernate.xml

<!-- LookupDAO: Hibernate implementation -->

<bean id="lookupDAO" class="net.smarthings.dao.hibernate.LookupDAOHibernate" >

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

 

Class LookupManagerImpl 中有这么一个方法,用于得到角色的List

 public List getAllRoles() {

              // LookupManagerImp 将真正的数据处理委派给 LookupDAOHibernate

        List roles = dao.getRoles();

        List list = new ArrayList();

              …….

              …..

}

 

从这里可以看出AppFuse的各层代码职责分配的非常清晰,包括Spring的配置文件。

你可能感兴趣的:(AppFuse1.8中IOC的使用.)