spring获取bean对象(普通Java类获取Spring的bean traceofsun的专栏 博客频道 CSDN.NET)
分类:
Extjs开发
2010-08-13 09:47 451人阅读 评论(0) 收藏 举报在SSH集成的前提下 。某些情况我们需要在Action以外的类中来获得Spring所管理的Service对象 。
之前我在网上找了好几好久都没有找到合适的方法 。例如:
ApplicationContext context = new ClassPathXmlApplicationContext();
当时我觉得没有这个必要 ,浪费内存 。后来我终于想出了一个解决方法 。在此拿来给大家参考下 ,希望对大家有帮助 。
1.创建一个类并让其实现org.springframework.context.ApplicationContextAware接口来让Spring在启动的时候为我们注入ApplicationContext对象.
示例代码:
view plaincopy to clipboardprint?
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class MyApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext context;//声明一个静态变量保存
@Override
public void setApplicationContext(ApplicationContext contex)
throws BeansException {
this.context=contex;
}
public static ApplicationContext getContext(){
return context;
}
2.在applicationContext.xml文件中配置此bean ,以便让Spring启动时自动为我们注入ApplicationContext对象.
例:
<!-- 这个bean主要是为了得到ApplicationContext 所以它不需要其它属*-->
<bean class="org.ing.springutil.MyApplicationContextUtil"></bean>
3.有了这个ApplicationContext之后我们就可以调用其getBean("beanName")方法来得到由Spring 管理所有对象.
1. 通过ApplicationContextAware
2. 通过WebApplicationContext
外部系统 访问已初始化的spring实例, 目前找到两种方法
1. 通过ApplicationContextAware
2. 通过WebApplicationContext先介绍一点需求 。 业务系统要和gis系统进行集成 ,本来是分来的两个war包通过Web Service调用 , 现在要合到一个war中 ,一起部署 。业务系统使用的架构是以spring基础 ,struts+ibatis+xfire 。 GIS的架构 ,主要是jsf, arc-gis (对这部分不太了解) 。 现在GIS系统需要调用业务系统的数据 ,既然两个系统现在准备合成一个系统 ,Web Service的方式肯定是一种不太可取的方法 ,本地调用才有保证效率 。
但是 ,问题出在了GIS系统,不是按照spring架构的IOC方式注入的 。现在需要开一个口 ,给GIS系统spring的全局Context ,可以让 GIS不通过IOC也可以得到beans。昨天试了一下,Spring支持这种外来的功能 ,目前发现了两种办法 。不过这两种办法 ,都存在着风险 ,后面会说到 。
1. 通过ApplicationContextAware。写一个子类 ,实现ApplicationContextAware的方法 ,然后把这个类配置到Spring容器中 。启动的时候 ,容器会自动调用setApplicationContext的方法 , 把容器全局的context给传进来 , 赋值给静态变量ctx 。然后 ,非spring模块 ,想调用spring容器实例的时候 ,可以直接通过SetSpringContext .getCtx(); 获得这个context 。 因此 ,方法不依赖于servlet 。
--------------------------------------------------------------------------------------------------------
package com.dvs.test;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;public class SetSpringContext implements ApplicationContextAware{
private static ApplicationContext ctx;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ctx = applicationContext;
}public static ApplicationContext getCtx() {
return ctx;
}public static void setCtx(ApplicationContext ctx) {
SetSprContext.ctx = ctx;
}}
险:
1) 由于spring中的单例和Gof所描述的单例不一样 。因此,其实applicationContext是代码级非单例的 ,把非静态的对象给一个静态对象 ,这是不安全的 。
2) 由于把整个的spring全局实例,对外暴露 ,因此给了其他系统 ,可以修改spring容器全局变量的功能 ,容易受到恶意篡改 ,或者安全的漏洞 。2. 通过WebApplicationContext 。这种方法的出发点 ,是两个工程在一个war包里面 ,因此ServletContext是全局共享的 。调用 WebApplicationContextUtils.getWebApplicationContext(getServletContext()); 传一个ServletContext , 然后获得WebApplcationContext的全局实例, 再把这个实例子 ,传给一个静态变量 ,给Servlet调用 。
--------------------------------------------------------
package com.dvs.test;import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;public class GetSpringContext extends HttpServlet {
/**
*
*
*
*
*
* 容器起动的时候 ,加载这个servlet 。
*/
public void init(){
WebApplicationContext wac =WebApplicationContextUtils.getWebApplicationContext(getServletContext());
SpringDTO.setCtx(wac);
}public void doGet(HttpServletRequest request, HttpServletResponse response) {
// wac =WebApplicationContextUtils.getWebApplicationContext(getServletContext());
}
}中间的类:
package com.dvs.test;import org.springframework.web.context.WebApplicationContext;
/**
* @author Conan
*
*/
public class GetSpringContextFactory<E> {public E getBean(String name) {
WebApplicationContext wac = SpringDTO.getCtx();
return (E) wac.getBean(name);
}}
中间的类:
package com.dvs.test;import org.springframework.web.context.WebApplicationContext;
public class SpringDTO {
private static WebApplicationContext ctx;
public static WebApplicationContext getCtx() {
return ctx;
}public static void setCtx(WebApplicationContext ctx) {
SprFactory.ctx = ctx;
}}
调用的类:
package com.dvs.test;import java.util.List;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.dvs.sec.model.usergroup.UserGroupDTO;
import com.dvs.sec.service.usergroup.UserGroupService;public class TestSpring extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) {
test();
}public void test(){
GetSpringContextFactory ctx = new GetSpringContextFactory();
UserGroupService ug = (UserGroupService) ctx.getBean("userGroupService");
try {
List
for(UserGroupDTO dto:list){
System.out.println(dto.getPk());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}----------------------------------------------------------
风险:
1. 与第一种方法一样 ,都是给外部一个static变量 ,把全局的spring实例给外部用 。
2. 这种方式,外部调用的时候必需依赖与Servlet ,并且得到的是Spring Context的子类。目前来看 ,第一种方式,比第二更灵活 ,但风险更大 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!