spring mvc里,jsp中怎么获取bean

spring mvc里,jsp中怎么获取bean,第1张

首先,获取的 bean 的时候要保证或取得的 bean 必须携带 spring 容器注入的属性,这里举一个简单的例子:

以 dao,service,action 这三种常见的数据模型,业务模型,控制器来举例子,(当然你使用 spring mvc 都是一样的,只不过省掉了 action,但都是控制器,你懂得):

如果jsp 视图需要接受一个 service 的 bean,必须要保证该 service 的 bean 中含有 注入的 dao 属性,这个懂吧?,如果直接在 jsp 中 new(实例化对象),这样将会丢失属性的,因为内存区域完全开辟了新的堆空间,跟 spring 容器所管理的 bean 完全不是一个,那么问题就来了,怎么样才能简单的得到这个拥有注入属性的 bean 呢?

可以尝试将该 bean 封装为控制器(controller)中的一个成员(属性),之后通过web 容器内置的request ,session ,application 等作用域来进行封装,这就是简单的解决办法了

//spring的父子容器

spring相当于父容器,springmvc相当于子容器。

1、在同一个容器中,可以任意访问对象

2、子容器可以访问父容器的对象   比如:control中可以注入到service中

3、父容器不能访问子容器的对象

Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件,这些对象被称为 Spring Beans。

Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。

容器接口在 orgspringframeworkbeansfactoryBeanFactory中被定义。BeanFactory 和相关的接口,比如BeanFactoryAware、DisposableBean、InitializingBean,仍旧保留在 Spring 中,主要目的是向后兼容已经存在的和那些 Spring 整合在一起的第三方框架。

在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory 会被优先选择。否则,一般使用的是 ApplicationContext,除非你有更好的理由选择 BeanFactory。

Application Context 是 BeanFactory 的子接口,也被称为 Spring 上下文。

它增加了企业所需要的功能,比如,从属性文件中解析文本信息和将事件传递给所指定的监听器。这个容器在 orgspringframeworkcontextApplicationContext interface 接口中定义。

Bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。

Spring 框架支持以下五个作用域,分别为 singleton、prototype、request、session 和 global session,5种作用域说明如下所示:

Singleton 是单例类型,就是在创建起容器时就同时自动创建了一个 bean 的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton 作用域是 Spring 中的缺省作用域。

Prototype 是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的 bean 应该使用 prototype 作用域,而对无状态的bean则应该使用 singleton 作用域。

Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,以下介绍一些关键节点。

Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁。

spring xml中定义

<!--spring 工具类-->

<bean id="springContextUtil" class="comskylinepubutilsSpringContextUtil"/>

SpringContextUtil的代码如下

package comskylinepubutils;

import orgspringframeworkbeansBeansException;

import orgspringframeworkcontextApplicationContext;

import orgspringframeworkcontextApplicationContextAware;

import javautilLocale;

/

Spring 获取 bean工具类

Author: skyline{>

       Spring使用 基本的JavaBean 来完成以前只可能由EJB完成的事情,是个分层架构。Spring创建bean都需要通过 读取 、 解析 、 校验配置文件, 然后注册创建成Bean。 Spring是一个Bean容器 , 主要作用是替我们管理bean对象 (简单的Java类对象的生命周期)。不管框架如何强大,还是需要我们程序员来告诉其一些必要信息的(比如要 管理的bean对象的类相关信息、是否开启组件扫描 等),这些我们称之为对 Spring框架的配置 ,目前主流的配置方式是 通过使用配置文件或注解。

        Spring中最核心的两个类: DefaultListableBeanFactory、XmlBeanDifinitionReader。DefaultListableBeanFactory 是整个bean加载的核心部分,是Spring注册及加载bean的默认实现 。XmlBeanDefinitionReader 主要使用reader属性对资源文件进行读取和注册。

        XML配置文件读取是Spring中重要的功能,大部分Spring大部分功能都是 以配置作为切入点 。 XmlBeanFactory 继承自 DefaultListableBeanFactory ,而对于 DefaultListableBeanFactory 不同的地方其实是在 XmlBeanFactory 中使用了自定义的XML读取器 XmlBeanDefinitionReader ,主要用于从XML文档中读取 BeanDefinition, 实现了个性化的 BeanDefinitionReader 读取, DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 并实现了 ConfigurableListableBeanFactory 以及 BeanDefinitionRegistry 接口。

        Spring的配置文件读取是通过ClasaPathResource进行封装的 ,如:new ClassPathResource("beanxml")。在java中, 将不同来源的资源的读取逻辑抽象成URL ,通过注册不同的 handler来处理。 一般handler的类型使用不同的前缀,URL没有默认定义相对的path路径,也 没有提供相关方法对资源进行检查 ,顾Spring对其内部需要使用到的资源做了属于自己的抽象结构, 用Resource接口来封装底层资源。

        Resource 接口继承 InputStreamSource(封装了任何能返回InputStream的类)。

        Resource接口抽象了所有Spring内部使用到的底层资源 ,首先它定义了3个能判断当前资源状态的方法: 存在性(exists)、可读性(isReadable)、是否处于打开状态(isOpen) 。有了Resource接口便可以对所有资源进行统一处理。 ClassPathResource 中的实现是通过class或 classLoader 提供的底层方法进行调用。以此完成对配置文件资源的封装。

        当通过Resource相关类完成了对配置文件进行封装,接下来由 XmlBeanDefinitionReader 完成对配置文件的读取工作。

       XML文件的验证模式有两种:DTD、XSD(XML Schema)

        DTD即文档类型定义, 是一种XML约束模式语言,是XML文件的验证机制 。是一种保证XML文档格式正确的有效方法, 可以通过比较XML文档和DTD文件来查看文档是否符合规范,元素和标签的使用是否正确 。一个DTD文档包含:元素的定义规则、元素间关系的定义规则、元素可使用的属性、可使用的实体或符号规则。 要使用DTD验证模式需要在XML文件的头部声明。

        XML Schema语言就是XSD。   XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。也可以 通过XML Schema指定一个XML文档所允许的结构和内容 。XML Schema本身也是一个XML文档,符合XML语法结构,可以用通用的XML解析器解析它。    

        使用XML Schema文档对XML实例进行校验,要声明名称空间和指定该名称空间所对应的XML Schema文档存储位置 。通过schemaLocation属性来指定名称空间所对应的XML Schema文档的存储地址(1、名称空间URL;2、该名称空间所标识的XML Schema文件地址或URL地址)。

      另外验证模式通过 XmlBeanDefinitionReader 中的setValidationMode方法进行设定。而 Spring 用来检测验证模式的方法实际上就是判断是否包含 DOCTYPE ,如果包含就是 DTD ,否则就是 XSD 。

        XML文件经过验证模式,交由DocumentLoader进行解析成对应的 Document。 而解析的过程中存在这么一环节:(EntityResolver) 根据声明去寻找对应的DTD定义,以便对文档进行验证认证 。也可以通过setEntityResolver设置DTD定义。EntityResolver它用来接收两个参数publicId和systemId,xsd格式文件通常publicId为null。而对于不同的验证模式采用不同的解析器进行解析,并把文件转换成Document文件,用于提取及注册bean。

          Document 文件通过 BeanDefinitionDocumentReader 进行内部逻辑处理,并提取root用于作为参数继续完成BeanDefinition的注册。

通过AbstractApplicationContext#refresh()提供了在加载完配置文件后的启动过程。以SpringBoot的Web环境来看启动过程(文末有spring容器的启动过程及区别)

1prepareRefresh():由于在此时还没有加载servlet容器,所以servletContext=null,servletConfig=null,还没有进行初始化propertySource,添加了几个ApplicationListeners。

2obtainFreshBeanFactory():创建BeanFactory,即DefaultListableBeanFactory

3prepareBeanFactory():对DefaultListableBeanFactory进行属性填充。如:添加类加载器,添加BeanPostProcessor等等。

4postProcessBeanFactory():在上面prepareBeanFactory()公共的之后,提供子类的特殊处理,注册特殊的后处理器,此处为ServletWebServerApplicationContext的具体实现。

5invokeBeanFactoryPostProcessors():主要是扫描包,注册成BeanDefinition,对类配置的信息解析成BeanDefinition的属性。然后执行实现了BeanFactoryPostProcessor接口的bean的postProcessBeanFactory()方法。

对于BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor,执行postProcessBeanDefinitionRegistry

ConfigurationWarningsApplicationContextInitializer类型的processor,检查包名是否异常

获取类型为BeanDefinitionRegistryPostProcessor并且是PriorityOrdered优先排序类型的beanDefinition

上面获取postProcessorNames的具体实现如下

调用刚获取到的currentRegistryProcessor列表中的bean的postProcessBeanDefinitionRegistry()方法

获取到启动类

对启动类开始进行解析,包装成SourceClass,开始解析

获取到需要扫描的包信息,开始进行解析

解析是否有includeFilters,excludeFilters,lazyInit等属性,解析basePackage,basePackageClasses配置,如果没有,则根据启动类的包名获取,最终获得需要扫描的包。

解析包下所有beanDefinition,遍历并逐个解析。  如果实现了AnnotatedBeanDefinition接口,解析是否有lazy,Primary,DependsOn,Role,Description等注解并对beanDefinition进行相应属性设置。   检查是否在beanDefinitionMap中,如果不存在则将beanDefinition注册到beanDefinitionMap中。

对获取到的包下的beanDefinition进行遍历处理。处理是否import,ImportResource,Bean注解,处理实现的接口。

处理完BeanDefinitionRegistryPostProcessor类型的bean之后,处理之前注册的处理器,前两个处理器没做任何处理,第三个处理器ConfigurationClassPostProcessor,对目前加载的所有的beanDefinition进行处理。如果是启动类,生成代理类并替换原来的beanClass

获取实现了BeanFactoryPostProcessor接口的类,去除了上面已经解析过的internalConfigurationAnnotationProcessor,根据是否排序进行分类,然后按照PriorityOrdered,Ordered,nonOrdered以此执行。

6registerBeanPostProcessors():获取实现了BeanPostProcessor的bean,并根据是否实现order接口进行排序,并按顺序注册到beanPostProcessors中。

7initMessageSource():

8initApplicationEventMulticaster():注册事件广播器

9onRefresh():获取ServletWebServerFactory(tomcatServletWebServerFactory),创建TomcatWebServer,然后initServletPropertySources

创建TomcatWebServer之后获取需要初始化的servlet,filter

将servlet添加到servletContext中

将filter添加到servletContext中

10registerListeners():在事件广播器中注册监听器,注册监听器name,如果earlyApplicationEvents存在,则广播事件。

11finishBeanFactoryInitialization():实例化bean

先进行实例化之前的 *** 作,再实例化bean。

如果有实现InstantiationAwareBeanPostProcessor, 则执行postProcessBeforeInstantiation

根据实例化策略进行实例化(这里是cglib)包装成BeanWrapper

实例化之后执行后处理

执行postProcessProperties

属性设置,在AutowiredAnnotationBeanPostProcessor中进行依赖注入

是否实现BeanNameAware,BeanClassLoaderAware,BeanFactoryAware等接口

init之前

调用自定义的init方法,在InitDestroyAnnotationBeanPostProcessor中处理

如果实现了InitializingBean,执行afterPropertiesSet()方法

然后执行init之后的方法

12finishRefresh():主要做的事情是启动tomcat,并发布事件

逐个listener去匹配事件

以下为spring环境启动与web环境启动的相同和不同:

1prepareRefresh():区别在于initPropertySources()的实现不同,spring上下文为AnnotationConfigApplicationContext,web上下文AnnotationConfigServletWebServerApplicationContext

2obtainFreshBeanFactory():相同

3prepareBeanFactory():相同

4postProcessBeanFactory():spring使用的AbstractApplicationContext的默认处理,没有提供实现,web提供了实现注册了特殊的处理器

5invokeBeanFactoryPostProcessors():相同

6registerBeanPostProcessors():相同

7initMessageSource():相同

8initApplicationEventMulticaster():相同

9onRefresh():spring什么都没做,使用的AbstractApplicationContext的默认实现,web提供了创建web容器的过程

10registerListeners():相同

11finishBeanFactoryInitialization():相同

12finishRefresh():spring主要做的事情是发布事件,web容器多了一步启动web容器

综上:web环境和spring环境启动容器流程基本相同,spring默认使用AbstractApplicationContext的实现,web多了properties解析,注册特殊处理器,创建webServer和启动webServer的过程。

以上就是关于spring mvc里,jsp中怎么获取bean全部的内容,包括:spring mvc里,jsp中怎么获取bean、java在当前容器如何获得父容器对象、Spring容器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/9637842.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存