在完全由Spring管理的环境中使用Spring的Context获取Bean实例
2015-02-06 16:25
441 查看
在大型的应用中,常常会有很灵活的需求,而在使用了框架之后,虽然可以大大提高开发的效率,但同时,也把我们框到一个架子中了。
下面先说一下我遇到的问题,事情大概是这样的:
这是整个应用的一部分,应用启动的时候,我需要启动这个Server线程,这个Server线程中持 有一个ActionFactory实例,在run方法中,每次用ActionFactory实例获取某个Action的实例。话是这样讲没错了。但仔细分析一下,整个应用中只会有一个Server实例,也就是虽然ActionFactory上注解了Scope为Prototype,但其实整个生命周期还是只有一个ActionFactory实例,然后就出问题了,由于这个ActionFactory中保持了每个Action的一个实例作为一个域,所以在server中调用ActionFactory#getAction的时候,对与一个Action名称,返回的是同一个Action实例。这就麻烦了,线程不安全了。想了一下,也没有其他的方法(有更好的方法请留言),只能在ActionFactory里手动获取各个Action,或者干脆手动获取ActionFactory,因为在ActionFactory上加了Scope=Prototype,所以获取一次ActionFactory,就会重新获取ActionFactory所持有的所有的Action对象,而各个Action上也加了Scope=Prototype,所以每个Action对象也是新的。显然没有在ActionFactory里手动获取各个Action这种方法好。可以不用每次想获取一种Action的实例的时候,还获取其他的Action实例了。
正题:
如何在完全由Spring管理的环境中使用Spring的Context获取Bean实例?如何在一个singleton bean要引用另外一个非singleton bean?
此部分来自参考中的博客中的内容。
看了一下Spring提供了两种方式,其实是一种,跟Struts2获取Context的方法一致
实现ApplicationContextAware接口
直接把这个类注入到想使用Context获取Bean的类中就行了。
继承实现了ApplicationContextAware接口的ApplicationObjectSupport抽象类
这个类中已经实现了一部分,用起来就很简单了。
注:
Spring中有很多实现了Aware接口的子接口以及相对应的抽象类,实现了这些接口的类可以获取相对应的Spring的各种资源。比如,我们的bean实现BeanFactoryAware,spring会在bean实例化(getBean)阶段回调该setBeanFactory方法,注入BeanFactory实例。上边例子中的ApplicationContextAware接口的实现,可以获取ApplicationContext的实例。
over.
参考:
1.http://my.oschina.net/lilw/blog/172738
2.http://www.blogjava.net/syniii/archive/2010/11/24/338906.html
3.http://blog.csdn.net/java2000_wl/article/details/7378025
4.http://blog.csdn.net/luosijin123/article/details/8467654
下面先说一下我遇到的问题,事情大概是这样的:
@Component @Scope("prototype") public class Action1 implements Action{ ..... } @Component @Scope("prototype") public class Action2 implements Action{ ..... } @Component @Scope("prototype") public class Action3 implements Action{ ..... }
@Component @Scope("prototype") public class ActionFactory{ @Autowired public Action1 action1; @Autowired public Action2 action2; @Autowired public Action3 action3; .... public Action getAction(String action){ ...根据条件返回actionx } }
@Componment public Server implements Runnable{ @Autowired public ActionFactory actionFactory; public void run(){ .... Action action = actionFactory.getAction("actionx's name"); new Thread(new ThreadTool(action)).start(); .... } }
这是整个应用的一部分,应用启动的时候,我需要启动这个Server线程,这个Server线程中持 有一个ActionFactory实例,在run方法中,每次用ActionFactory实例获取某个Action的实例。话是这样讲没错了。但仔细分析一下,整个应用中只会有一个Server实例,也就是虽然ActionFactory上注解了Scope为Prototype,但其实整个生命周期还是只有一个ActionFactory实例,然后就出问题了,由于这个ActionFactory中保持了每个Action的一个实例作为一个域,所以在server中调用ActionFactory#getAction的时候,对与一个Action名称,返回的是同一个Action实例。这就麻烦了,线程不安全了。想了一下,也没有其他的方法(有更好的方法请留言),只能在ActionFactory里手动获取各个Action,或者干脆手动获取ActionFactory,因为在ActionFactory上加了Scope=Prototype,所以获取一次ActionFactory,就会重新获取ActionFactory所持有的所有的Action对象,而各个Action上也加了Scope=Prototype,所以每个Action对象也是新的。显然没有在ActionFactory里手动获取各个Action这种方法好。可以不用每次想获取一种Action的实例的时候,还获取其他的Action实例了。
正题:
如何在完全由Spring管理的环境中使用Spring的Context获取Bean实例?如何在一个singleton bean要引用另外一个非singleton bean?
此部分来自参考中的博客中的内容。
看了一下Spring提供了两种方式,其实是一种,跟Struts2获取Context的方法一致
实现ApplicationContextAware接口
@Service public class SpringContextHelper implements ApplicationContextAware { private ApplicationContext context; //提供一个接口,获取容器中的Bean实例,根据名称获取 public Object getBean(String beanName) { return context.getBean(beanName); } @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; } }
直接把这个类注入到想使用Context获取Bean的类中就行了。
继承实现了ApplicationContextAware接口的ApplicationObjectSupport抽象类
这个类中已经实现了一部分,用起来就很简单了。
@Service public class SpringContextHelper2 extends ApplicationObjectSupport { //提供一个接口,获取容器中的Bean实例,根据名称获取 public Object getBean(String beanName) { return getApplicationContext().getBean(beanName); } }
注:
Spring中有很多实现了Aware接口的子接口以及相对应的抽象类,实现了这些接口的类可以获取相对应的Spring的各种资源。比如,我们的bean实现BeanFactoryAware,spring会在bean实例化(getBean)阶段回调该setBeanFactory方法,注入BeanFactory实例。上边例子中的ApplicationContextAware接口的实现,可以获取ApplicationContext的实例。
over.
参考:
1.http://my.oschina.net/lilw/blog/172738
2.http://www.blogjava.net/syniii/archive/2010/11/24/338906.html
3.http://blog.csdn.net/java2000_wl/article/details/7378025
4.http://blog.csdn.net/luosijin123/article/details/8467654
相关文章推荐
- 使用SpringContextHolder获取bean实例
- 为何在新线程中使用注解获取不到Spring管理的Bean
- Spring学习之使用factorybean获取bean实例
- 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法
- 获取SpringMVC上下文bean实例-SpringContextUtil
- mvn中,使用spring中获取bean实例
- 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法
- spring学习(五)ClassPathXmlApplicationContext的getBean获取实例bean
- 自定义SpringContextHolder获取bean实例
- 在spring来管理实例对象prototype和singleton的选择.针对action如何使用
- 在servlet中获取spring管理的bean
- 一种获取spring环境上下文方法:SpringContextUtil
- spring获取bean 实例
- Struts 2在Action中获取Spring容器中所有Bean实例名称的方法
- 使用dom4j:读取spring配置文件,实例化bean对象并注入依赖对象
- 通过ApplicationContextAware获取spring容器中的bean
- 使用dom4j:读取spring配置文件,实例化bean对象并注入依赖对象
- 获取Spring管理的对象实例
- 从spring容器中得到bean_使用类构造器实例化_使用静态工厂方法实例化_使用实例工厂方法实例化_例子
- Java类获取Spring的applicationContext.xml文件中的bean