怎样获取 spring 已经注解的bean

怎样获取 spring 已经注解的bean,第1张

不用配置xml,直接java代码实现,参考代码如下:public class GetApplicationContext {private static class ApplicationContextHolder {// 单例变量private static ApplicationContext AC = new FileSystemXmlApplicationContext("classpath:applicationContextxml");}// 私有化的构造方法,保证外部的类不能通过构造器来实例化。private GetApplicationContext() {}// 获取单例对象实例public static ApplicationContext getInstance() {if (ApplicationContextHolderAC == null) {ApplicationContextHolderAC = new FileSystemXmlApplicationContext("classpath:applicationContextxml");}return ApplicationContextHolderAC;}}获取所有spring自动装配的bean://获取spring装配的bean个数GetApplicationContextgetInstance()getBeanDefinitionNames()length;//逐个打印出spring自动装配的bean。根据我的测试,类名第一个字母小写即bean的名字for(int i=0;i<33;i++){Systemoutprintln( GetApplicationContextgetInstance()getBeanDefinitionNames()[i]);}然后通过下面的代码获取到spring注解装配的bean供自己使用:StorageReturnService ossService = (StorageReturnService) GetApplicationContextgetInstance()getBean("storageReturnServiceImpl");怎样获取 spring 已经注解的bean

1、web容器启动,开始扫描所有被指定的spring配置文件。 2、根据配置文件,实例化所有的bean对象,以java语法创建。 3、加载spring配置文件配置的对象依赖关系,将有依赖关系的bean注入到相应的对象中。 你这里报错是因为,datasource对象还没有

先实例化这个Bean

使用这个Bean的set方法可以设置属性值

使用这个Bean的get方法可以获取属性值

例如有一个Bean名位PersonBean:

public class PersonBean{

private String name;

private int age;

public void setName(String name){

thisname = name;

}

public void setAge(String age){

thisage= age;

}

public String getName(){

return name;

}

public int getAge(){

return age;

}

}

我们可以实例化这个Bean并设置属性

PersonBean per = new PersonBean();

persetName("yang");

persetAge(18);

然后将这个bean放到session中

sessionsetAttribut("Person",per);

当我们想要在另一个类中取得该bean中的值时

先从session中获取这个bean的对象

PersonBean per = (PersonBean )sessiongetAttribut("Person");

然后用get方法取得值

String name = pergetName();

int age = pergerAge();

<bean id="springBean" scope="prototype" class=""<property name="name" value="chen"/</bean<bean id="myAction" scope="prototype" class=""<property name="springBean" ref="springBean"/</bean如果是j2ee应用,启动web应用时将会自动加载ApplicationContext实例(Spring容器负责创建Bean实例)一旦struts2的myAction实例化,其中的SpringBean也会被自动注入进来,从而达到使用SpringBean的目的。[问题]但是仍有需要通过代码来调用SpringBean的情况:1)对于不是由spring创建管理的类,如在java 代码中直接使用new去创建一个对象,并且想在这个对象中使用SpringBean;因为这个对象并不是由Spring容器创建管理的类,所以即使它有setter方法,容器的springBean也不会被注入。2)动态更改springBean中的属性值,如在代码运行时,name值需要发生变动;3)对于一个独立的应用程序[解决]定义一个非Spring容器创建管理的类public class NonSpringClass implements ServletContextAware {private SpringBean springBean;//如果 testGetBean不是被Spring容器创建管理,即使它有setter方法,容器的springBean也不会被注入。public void setSpringBean(SpringBean springBean){thisspringBean=springBean;}//利用ApplicationContext 从spring容器中获得springBean;//Spring有两个核心接口BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口,//它们代表了Spring容器,Spring容器是产生Bean的工厂,用于管理容器中的Bean。

最近在使用Spring MVC过程中遇到了一些问题,网上搜索不少帖子后虽然找到了答案和解决方法,但这些答案大部分都只是给了结论,并没有说明具体原因,感觉总是有点不太满意。

更重要的是这些所谓的结论大多是抄来抄去,基本源自一家,真实性也有待考证。

那作为程序员怎么能知其所以然呢?

此处请大家内心默读三遍。

用过Spring 的人都知道其核心就是IOC和AOP,因此要想了解Spring机制就得先从这两点入手,本文主要通过对IOC部分的机制进行介绍。

在开始阅读之前,先准备好以下实验材料。

IDEA 是一个优秀的开发工具,如果还在用Eclipse的建议切换到此工具进行。

IDEA有很多的快捷键,在分析过程中建议大家多用Ctrl+Alt+B快捷键,可以快速定位到实现函数

Spring bean的加载主要分为以下6步:

查看源码第一步是找到程序入口,再以入口为突破口,一步步进行源码跟踪。

Java Web应用中的入口就是webxml。

在webxml找到ContextLoaderListener ,此Listener负责初始化Spring IOC。

contextConfigLocation参数设置了bean定义文件地址。

下面是ContextLoaderListener的官方定义:

翻译过来ContextLoaderListener作用就是负责启动和关闭Spring root WebApplicationContext。

具体WebApplicationContext是什么?开始看源码。

从源码看出此Listener主要有两个函数,一个负责初始化WebApplicationContext,一个负责销毁。

继续看initWebApplicationContext函数。

在上面的代码中主要有两个功能:

进入CreateWebAPPlicationContext函数

进入determineContextClass函数。

进入configureAndReFreshWebApplicaitonContext函数。

WebApplication Context有很多实现类。 但从上面determineContextClass得知此处wac实际上是XmlWebApplicationContext类,因此进入XmlWebApplication类查看其继承的refresh()方法。

沿方法调用栈一层层看下去。

获取beanFactory。

beanFactory初始化。

加载bean。

读取XML配置文件。

XmlBeanDefinitionReader读取XML文件中的bean定义。

继续查看loadBeanDefinitons函数调用栈,进入到XmlBeanDefinitioReader类的loadBeanDefinitions方法。

最终将XML文件解析成Document文档对象。

上一步完成了XML文件的解析工作,接下来将XML中定义的bean注册到webApplicationContext,继续跟踪函数。

用BeanDefinitionDocumentReader对象来注册bean。

解析XML文档。

循环解析XML文档中的每个元素。

下面是默认命名空间的解析逻辑。

不明白Spring的命名空间的可以网上查一下,其实类似于package,用来区分变量来源,防止变量重名。

这里我们就不一一跟踪,以解析bean元素为例继续展开。

解析bean元素,最后把每个bean解析为一个包含bean所有信息的BeanDefinitionHolder对象。

接下来将解析到的bean注册到webApplicationContext中。接下继续跟踪registerBeanDefinition函数。

跟踪registerBeanDefinition函数,此函数将bean信息保存到到webApplicationContext的beanDefinitionMap变量中,该变量为map类型,保存Spring 容器中所有的bean定义。

Spring 实例化bean的时机有两个。

一个是容器启动时候,另一个是真正调用的时候。

相信用过Spring的同学们都知道以上概念,但是为什么呢?

继续从源码角度进行分析,回到之前XmlWebApplication的refresh()方法。

可以看到获得beanFactory后调用了 finishBeanFactoryInitialization()方法,继续跟踪此方法。

预先实例化单例类逻辑。

获取bean。

doGetBean中处理的逻辑很多,为了减少干扰,下面只显示了创建bean的函数调用栈。

创建bean。

判断哪种动态代理方式实例化bean。

不管哪种方式最终都是通过反射的形式完成了bean的实例化。

我们继续回到doGetBean函数,分析获取bean的逻辑。

上面方法中首先调用getSingleton(beanName)方法来获取单例bean,如果获取到则直接返回该bean。方法调用栈如下:

getSingleton方法先从singletonObjects属性中获取bean 对象,如果不为空则返回该对象,否则返回null。

那 singletonObjects保存的是什么?什么时候保存的呢?

回到doGetBean()函数继续分析。如果singletonObjects没有该bean的对象,进入到创建bean的逻辑。处理逻辑如下:

下面是判断容器中有没有注册bean的逻辑,此处beanDefinitionMap相信大家都不陌生,在注册bean的流程里已经说过所有的bean信息都会保存到该变量中。

如果该容器中已经注册过bean,继续往下走。先获取该bean的依赖bean,如果镩子依赖bean,则先递归获取相应的依赖bean。

依赖bean创建完成后,接下来就是创建自身bean实例了。

获取bean实例的处理逻辑有三种,即Singleton、Prototype、其它(request、session、global session),下面一一说明。

如果bean是单例模式,执行此逻辑。

获取单例bean,如果已经有该bean的对象直接返回。如果没有则创建单例bean对象,并添加到容器的singletonObjects Map中,以后直接从singletonObjects直接获取bean。

把新生成的单例bean加入到类型为MAP 的singletonObjects属性中,这也就是前面singletonObjects()方法中获取单例bean时从此Map中获取的原因。

Prototype是每次获取该bean时候都新建一个bean,因此逻辑比较简单,直接创建一个bean后返回。

从相应scope获取对象实例。

判断scope,获取实例函数逻辑。

在相应scope中设置实例函数逻辑。

以上就是Spring bean从无到有的整个逻辑。

从源码角度分析 bean的实例化流程到此基本接近尾声了。

回到开头的问题,ContextLoaderListener中初始化的WebApplicationContext到底是什么呢?

通过源码的分析我们知道WebApplicationContext负责了bean的创建、保存、获取。其实也就是我们平时所说的IOC容器,只不过名字表述不同而已。

本文主要是讲解了XML配置文件中bean的解析、注册、实例化。对于其它命名空间的解析还没有讲到,后续的文章中会一一介绍。

希望通过本文让大家在以后使用Spring的过程中有“一切尽在掌控之中”的感觉,而不仅仅是稀里糊涂的使用。

spring在普通类中注入bean实例 或注入静态变量的bean Spring的注入有一个问题就是普通类没有办法获得Bean文件中的bean实例。这就是如果是在Web的Servlet环境中可以通过WebApplicationContextUtils,如果是普通类就不好处理了。

以上就是关于怎样获取 spring 已经注解的bean全部的内容,包括:怎样获取 spring 已经注解的bean、如何不通过依赖注入获取spring环境中的Bean、如何获取javabean的属性和值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/web/9623977.html

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

发表评论

登录后才能评论

评论列表(0条)

保存