zoukankan      html  css  js  c++  java
  • 普通Java类获取Spring的bean traceofsun的专栏 博客频道 CSDN.NET

    普通Java类获取Spring的bean - traceofsun的专栏 - 博客频道 - CSDN.NET

     


    普通Java类获取Spring的bean


    分类:
    Extjs开发


    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>
    * <servlet-name>GetSpringContext</servlet-name>
    * <servlet-class>com.dvs.test.GetSpringContext</servlet-class>
    * <load-on-startup>1</load-on-startup>
    * </servlet>
    * 容器起动的时候,加载这个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<UserGroupDTO> list= ug.getUserGroupList();
    for(UserGroupDTO dto:list){
    System.out.println(dto.getPk());
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    ----------------------------------------------------------
    风险:
    1. 与第一种方法一样,都是给外部一个static变量,把全局的spring实例给外部用。
    2. 这种方式,外部调用的时候必需依赖与Servlet,并且得到的是Spring Context的子类。


    目前来看,第一种方式,比第二更灵活,但风险更大。

  • 相关阅读:
    Docker
    Docker
    VIM
    Python
    Python
    VIM
    Python
    其他
    Java
    Java
  • 原文地址:https://www.cnblogs.com/lexus/p/2457764.html
Copyright © 2011-2022 走看看