Web开发中遇到关于spring注入的问题(尚未整理 仅供自己参考)

    Web开发中遇到关于spring注入的问题

首先深入了解一下什么是ApplicationContext:

web项目当中获取spring容器管理的类 管理的类

首先导入 import org.springframework.web.context.support.WebApplicationContextUtils;

 ServletContext stx=request.getSession().getServletContext();

//request对象中获取serverletContext

 ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(stx);

 myTest m=(myTest)ac.getBean("myTest");

 m.test();

myTest类文件

package edu.ncut.decloud.authorization.web.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.stereotype.Component;

import org.springframework.stereotype.Controller;

import org.springframework.stereotype.Repository;

import edu.ncut.decloud.kyc.dao.BBmDao;

@Component("myTest")//标签声明对象

public class myTest {

@Autowired

@Qualifier("bBmDao")

private BBmDao BBmDaoService;

public void test()

{

this.BBmDaoService.listAll();

}

}

获取servletContext的几种方式:

http://chen106106.iteye.com/blog/1318596

在北工大项目中之所以servlet可以直接注入是因为在

ublic class AbstractServlet extends HttpServlet {

private static final long serialVersionUID = 1L;  

  

    /** 

     * @see HttpServlet#HttpServlet() 

     */  

    public AbstractServlet() {  

        super();  

    }  

  

    public void init(ServletConfig configthrows ServletException {  

        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,  

                config.getServletContext());  //由于这里的代码使得所有的子类处于被spring管理的状态下

    }  

  

 

 

ApplicationContext实现了Beanfactory接口,我们可以从其中获取javabean对象。

ApplicationContext的中文意思是“应用前后关系”,它继承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在国际化支持、资源访问(如URL和文件)、事件传播等方面进行了良好的支持,被推荐为Java EE应用之首选,可应用在JavaAPPJava Web中。

 

ApplicationContext接口的众多实现类中,有3个是我们经常用到的(见表1-1),并且使用这3个实现类也基本能满足我们Java EE应用开发中的绝大部分需求。

1-1 ApplicationContext接口的常用实现类介绍

类 名 称

功 能 描 述

ClassPathXmlApplicationContext

从类路径ClassPath中寻找指定的XML配置文件,找到并装载

完成ApplicationContext的实例化工作。例如:

//装载单个配置文件实例化ApplicationContext容器

ApplicationContext cxt = new ClassPathXmlApplicationContext

("applicationContext.xml");

//装载多个配置文件实例化ApplicationContext容器

String[] configs = {"bean1.xml","bean2.xml","bean3.xml"};

ApplicationContext cxt = new ClassPathXmlApplicationContext(configs);

FileSystemXmlApplicationContext

从指定的文件系统路径中寻找指定的XML配置文件,找到并装载

完成ApplicationContext的实例化工作。例如:

//装载单个配置文件实例化ApplicationContext容器

ApplicationContext cxt = new FileSystemXMLApplicationContext

("beans.xml");

//装载多个配置文件实例化ApplicationContext容器

String[] configs = {"c:/beans1.xml","c:/beans2.xml"};

ApplicationContext cxt = new FileSystemXmlApplicationContext(configs);

XmlWebApplicationContext

Web应用中的寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。这是为Web工程量身定制的,使用WebApplicationContextUtils类的getRequiredWebApplicationContext方法可在JSPServlet中取得IoC容器的引用

 

 

 

、IOC 依赖注入

概念:这个概念要理解有一定的难度,我阐述一下我的理解:

它包括两个内容:

其一是控制

其二是反转

    那到底是什么东西的“控制”被“反转”了呢?我借鉴《Sring3.x 企业级开发》的例子:一部电影要拍摄要有导演、剧本、演员等,而剧本里的角色由哪些演员来扮演 ? 是谁控制呢?一般的思路是剧本里的角色被固定一个演员。“控制”是指选择一个角色扮演者的控制权,“反转”是指这种控制权从剧本中移除,转交到导演手中。这样剧本就活了,不会因为一个演员不干了,电影就不能拍了。

在软件中,即是某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定。可以灵活地去选择哪个具体实现的类,而不用修改调用类的代码。这就符合了开闭原则。

 

二、 Ioc的类型

1、 构造函数注入

Public class A{

Private B b;

Public A (B b){

This.b = b;

}

 

Public void hell(){

B.hell();

}

}

从上述代码可以看到在A 实例时通过构造函数对 B 进行实例化。

2、 属性注入

就是在调用类中要注入的类生成一个set 方法;在使用时通过调用这个方法来为该注入类注入对象。

3、 接口注入

将调用类所有依赖注入的方法抽取到一个借口中,调用类通过实现该借口提供的相应的注入方法。为了采取借口注入的方式,必须先声明一个借口。

 

 

三、 通过容器完成依赖关系的注入

提供一个容器来存储各个类的实例化和他们的关系,使他们完全解耦。Spring 就是这样做的,它帮住完成类的初始化与装配工作,让开发者从这些底层实现类的实例化、依赖关系装配等工作中脱离出来,专注于更有意义的业务逻辑开发工作, Spring 同过配置文件或注解描述类和类之间的依赖关系,自动完成类的初始化和依赖注入的工作。具体是如何来进行这些工作的呢?答案一定是 java 的反射机制。

 

 

 

 

下面我要看看spring 是如何实现 ioc 。

 

Spring通过一个配置文件来描述 Bean 即 Bean 之间的依赖关系,利用 java 的反射功能实例化 Bean 并建立Bean 之间的依赖关系。 Ioc 在完成基本的实例以为还提供了 Bean 实例的缓存、 Bean 生命周期管理、 Bean 的实例代理、事件发布、资源加载等功能。

对于Spring  的使用者而言, IOC  容器实际上是什么呢?我们可以说 BeanFactory 就是我们看到的 IoC  容器,当然了 Spring  为我们准备了许多种 IoC  容器来使用,这样可以方便我们从不同的层面,不同的资源位置,不同的形式的定义信息来建立我们需要的 IoC  容器。

 

BeanFactory:

Spring中最最核心的一个借口就是 BeanFactory, 它可以说是 spring 的心脏。 Spring 的 ioc 就是围绕着BeanFactory 展开的。

这是 spring IoC容器相关的核心类图 

上图简化了类之间的依赖关系,化繁为简,主要关于一下接口的继承体系。BeanFactory 接口定义了 spring 容器所能提供的最基本的服务。 同时, spring 又提供了几个其他的接口,作为对基本接口的扩展。DefaultListableBeanFactory  Spring 框架中最基本的 容器实现类,大多数的容器类都是在这个容器实现类的基础上进行功能的扩展。

     从接口的继承关系上来看,spring 遵守了单一职责原则,每一个接口只负责新增一个新的功能点,可以根据功能上的需要,选择不同的接口去实现。

 

BeanFactory 接口 :   spring ioc 容器核心接口 , 主要功能为根据 bean 的名称获取 bean 或 bean 的信息,提供的接口功能有:

查找是否有指定名称的 bean, 根据名称获取 bean, 根据名称获取所有的别名,根据名称获取 bean class 类型,根据名称判断 bean 是否是单例或 prototype  判断名称为 name 的 bean 是否与指定类型相匹配

n ListableBeanFactory 接口: 继承自 BeanFactory ,提供对容器内的 bean 的枚举与遍历功能,主要功能有:查找是否有指定名称 bean 的定义 , 获取容器内 bean 的数量及所有 bean 的名称 , 根据指定类型获取 bean 的集合

n HierarchicalBeanFactory 接口: 继承自 BeanFactory ,支持父子 BeanFactory 的继承,主要功能有判断当前 BeanFactory 中是否含有指定名称的 bean 、获取父 BeanFactory 。

n ConfigurableBeanFactory 接口: 继承自 HierarchicalBeanFactory 和 SingletonBeanRegistry接口,为beanFactory 添加了一些配置的功能,包括添加 BeanPostProcessor后置处理器、PropertyEditorRegistrar属性编辑器、别名,设置父beanFactory 、类加载器缓存,并提供了对Scope 的支持,除此之外还有销毁 bean 和容器中所有单例,获取后置处理器数量,类型转换器,复制 ConfigurableBeanFactory 信息,判断指定的bean 当前是否正在创建等功能。同时,由于该接口继承自 SingletonBeanRegistry接口,因此其也具有管理 beanFactory 中的单例对象的功能。

n AutowireCapableBeanFactory 接口: 继承自 BeanFactory ,提供自动装配的功能

n ConfigurableListableBeanFactory 接口 : 继承自ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory 此三个接口,并定义了获取 BeanDefinition 和预先实例化单例 bean 的功能。

n AbstractBeanFactory 类 : 对 BeanFactory 接口进行了基础性的实现,提供了ConfigurableBeanFactory 接口的所有功能。其功能和特点主要有:

通过继承自 DefaultSingletonBeanRegistry 类,提供了对单例对象的 cache 缓存可以根据 bean 名称,决定对象是 prototype 还是单例类型 , Bean 别名的支持

, Bean 定义 RootBeanDefinition 和 ChildBeanDefinition 的合并 , FactoryBean 创建 bean 与其本身的支持 , Bean 析构时调用 destroy() 方法或其本身配置的销毁方法进行后置处理 , 实现了HierarchicalBeanFactory 接口,支持 BeanFactory 容器的父子继承关系

本类给其子类留下了三个抽象方法:

boolean containsBeanDefinition(String beanName);

BeanDefinition getBeanDefinition(String beanName);

createBean(String beanName, RootBeanDefinition mbd, Object[] args);

 

 

 

 

 

 

ApplicationContext :

如果说 BeanFactory是 spring 的心脏那么 ApplicationContext 就是 Spring 的躯体了。 ApplicationContext 是从BeanFactory 扩展生成的。

ApplicationContext 接口:  spring context核心接口 , 其由 BeanFactory 接口的子接口扩展而来,因此具有 BeanFactory 的所有功能,又因为其继承了MessageSource, ApplicationEventPublisher, ResourcePatternResolver 接口,因此又具有国际化消息解析,资源加载, ApplicationEvent 事件发布的功能。在此接口自己定义的方法中提供了获取父 ApplicationContext 、获取自动装配 bean 工厂,获取启动时间和显示名称这四项功能。

n ConfigurableApplicationContext 接口 : 继承自ApplicationContext  Lifecycle 接口,为客户端提供了配置与定制 ApplicationContext 相关设置的功能,主要内容有:设置父ApplicationContext , 添加BeanFactory 后置处理器 BeanFactoryPostProcessor , 添加ApplicationListener , 获取ApplicationContext 内部的BeanFactory(ConfigurableListableBeanFactory 类型 ) , 刷新与关闭applicaionContext , 注册关闭时的shutdown hook , 判断当前applicationcontext 是否处于活动 (active 状态 )

n AbstractApplicationContext 类: 对 ApplicationContext 进行抽象实现,其内部的 refresh() 方法实现了 ApplicationContext 的启动流程,其 doClose() 方法则实现了 applicationcontext 的关闭流程。另外对其继承的多个接口中的方法,均有默认实现。

此类给子类留下了三个抽象方法:

     ConfigurableListableBeanFactory getBeanFactory();

void closeBeanFactory();

void refreshBeanFactory();

n AbstractRefreshableApplicationContext 类 : 继承自 AbstractApplicationContext 类,支持多次刷新。此类对其基类 AbstractApplicationContext 所留下的三个方法均进行了默认实现,其中在refreshBeanFactory() 方法中完成了刷新的功能,并调用了 createBeanFactory() 方法创建一个DefaultListableBeanFactory 对象来作为代理的内部类,在其子类的实现中将通过此beanFactory 来加载配置中的 BeanDefinition ,创建和管理 bean 。此类只留给子类一个抽象方法:

    void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) ;

从 beanFactory 中加载 beanDefinitions 。

n AbstractXmlApplicationContext 类 : 继承自AbstractRefreshableApplicationContext 类,其内部实现了从 xml 配置文件中加载和解析 beanDefinition

 

 

两者的区别:

1、 初始化,beanFactory 在初始化容器时,并未实例化 bean 直到第一次调用 getbean 时才会初始化该 bean ,而 applicationcontext 初始化时这在初始化应用上下文时就实例化所有单例的 bean 。

2、 Applicationcontext比 beanFactory 假如了一些更好使用的功能。而且 beanFactory 的许多功能需要通过编程实现而 Applicationcontext 可以通过配置实现。比如后处理 bean , Applicationcontext 直接配置在配置文件即可而 beanFactory 这要在代码中显示的写出来才可以被容器识别。

3、 beanFactory主要是面对与 spring 框架的基础设施,面对 spring 自己。而 Applicationcontex 主要面对与 spring 使用的开发者。基本都会使用 Applicationcontex 并非 beanFactory 。

 

 

webApplicationcontext

主要是面对与web 开发使用的。是通过 Applicationcontext扩展而来的。它允许从web 根目录的路径加载配置文件,而且还和 web 环境有一定的融合,比如 servletcontext 的相融合。 

 

Servletcontext中有 webApplicationcontext 的引用。在 webApplicationcontex 中也可以得到 Servletcontext 。如上图所示。

而且webApplicationcontext 可以随 web 容器的启动而启动 spring 的 ioc 容器。主要通过 web.xml 文件进行配置的。有两种方式一个是通过 servlet 一个是通过 web 容器的监听器。

 

 

 

总结:通过以上分析大家可以清楚的看到spring 是围绕着 beanFactory 来展开的。通过 bean 工厂来对在配置文件内的各个 bean 进行实例化装配。并在维护了一个容器来存储这些 bean ,其实内部就是一个map 对象。 Map 的 key 就是你在配置文件中的 beanid , map 的 value 就是 bean 的实例对象。使用时直接去容器中拿就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值