zoukankan      html  css  js  c++  java
  • 非spring组件servlet、filter、interceptor中注入spring bean

    问题:在filter和interceptor中经常需要调用Spring的bean,filter也是配置在web.xml中的,请问一下这样调用的话,filter中调用Spring的某个bean,这个bean一定存在吗?现在总是担心filter调用bean的时候,bean还没被实例化?

    答案:因为spring bean、filter、interceptor加载顺序与它们在 web.xml 文件中的先后顺序无关。即不会因为 filter 写在 listener 的前面而会先加载 filter。最终得出的结论是: ServletContext -> listener -> filter -> servlet 

    由于spring bean的初始化是在listener中声明的,因此filter时,spring bean已经实例。 

    注入bean方法:

    一、自定义一个工具类,在工具类中通过ApplicationContext获取bean

      自定义一个工具类,实现自ApplicationContextAware接口,接口的方法是setApplicationContext,我们实现它,并让其为我们服务,因为Spring在load自己的时候会将上下文环境填充进来。我们所要做的就是将得到的ApplicationContext保存下来用。

    @Component
    public class SpringUtil implements ApplicationContextAware {
    
        private static Logger log = LoggerFactory.getLogger(SpringUtil.class);
        
        /**
         * 当前IOC
         */
        private static ApplicationContext applicationContext;
    
        /*
         * @param arg0
         * 
         * @throws BeansException
         * 
         * @see
         * org.springframework.context.ApplicationContextAware#setApplicationContext
         * (org.springframework.context.ApplicationContext)
         */
        @Override
        public void setApplicationContext(ApplicationContext arg0) throws BeansException {
            log.info("====================arg0:"+arg0);
            applicationContext = arg0;
        }
        
        public static <T>T getBean(String id,Class<T> type){        
            return  applicationContext.getBean(id,type);
        }
    }

    需要注意的是该工具类需要纳入spring的bean管理(注解:增加扫描配置component-scan或bean.xml中配置)哟,否则applicationContext 将会是空的。

    二、自定义一个工具类,在工具类中通过BeanFactory 获取bean

      自定义一个工具类,实现自BeanFactoryAware 接口,接口的方法是setBeanFactory,我们实现它,并让其为我们服务,因为Spring在load自己的时候会将上下文环境填充进来。我们所要做的就是将得到的BeanFactory 保存下来用。

    
    
    @Component
    public class BeanHelper implements BeanFactoryAware {
        
        private static BeanFactory beanFactory;
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }
    
        public static <T>T getBean(String id,Class<T> type){        
            return  beanFactory.getBean(id,type);
        }
    }

    同样,需要注意的是该工具类需要纳入spring的bean管理(注解:增加扫描配置component-scan或bean.xml中配置)哟,否则applicationContext 将会是空的。

    二、使用了注解和静态化的方式来产生SpringFactory对象

      上文的方法有个麻烦的地方:需要配置。而Spring2.5及之后的版本实际上加入了注解的方式进行依赖项的注入,使用如下代码也许更好:

    public class SpringWiredBean extends SpringBeanAutowiringSupport {
        
        /**
         * 自动装配注解会让Spring通过类型匹配为beanFactory注入示例
         */
        @Autowired
        private BeanFactory beanFactory;
    
        private SpringWiredBean() {
        }
    
        private static SpringWiredBean instance;
    
        static {
            // 静态块,初始化实例
            instance = new SpringWiredBean();
        }
    
        /**
         * 实例方法 使用的时候先通过getInstance方法获取实例
         * 
         * @param beanId
         * @return
         */
        public <T>T getBean(String id,Class<T> type){        
            return  beanFactory.getBean(id,type);
        }
    
        public static SpringWiredBean getInstance() {
            return instance;
        }
    }

    但是要增加一个扫描,让spring能知道注解:

    <context:component-scan base-package="org.ahe"></context:component-scan>

    servlet中注入bean的方法

    步骤:

    1 配置spring文件

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> 
       <property name="sessionFactory" ref="sessionFactory"></property>
     </bean> 
     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
       <property name="dataSource" ref="dataSource" />
     </bean>

    2 在web.xml中加载spring的配置文件

    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
       classpath*:/spring/applicationContext_*.xml
      </param-value>
     </context-param>

    3 在servlet中获取名字为jdbcTemplat的bean.

    public class UserAuthorizationFilter extends HttpServlet {
    
    private WebApplicationContext wac;
    
        public void init(){
            //方法一:
           wac =WebApplicationContextUtils.getRequiredWebApplicationContext(
    
                 this.getServletContext());
    
            //方法二:
            wac = WebApplicationContextUtils.getWebApplicationContext(
              this.getServletContext());
    
           //方法一和方法二得到的结果是一样的。
    
         //wac的类型:
          org.springframework.web.context.support.XmlWebApplicationContext
    
        }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
    
         JdbcTemplate jdbcTemplate = (JdbcTemplate)wac.getBean("jdbcTemplate");
    
         String sql="select count(*) from customer where name='liwj' and password='1111111'";
    
         int num=jdbcTemplate.queryForInt(sql);
         if(num==1){   
           System.out.println("has");
          }else{   
          System.out.println("hasnot");     
    
       }
    
    }
  • 相关阅读:
    window.onload和document.ready/jquery页面加载事件等的区别
    JAVA面试题大全
    BIO NIO AIO的知识扫盲
    类的加载过程详细解释
    nginx的Rewrite和其他相关配置
    【微服务架构设计】DDD
    【重构】
    【多线程】Lock接口与其实现类
    【三方件】汇总
    【SpringBoot-SpringSecurity】安全响应头+防攻击 ~~ TODO
  • 原文地址:https://www.cnblogs.com/duanxz/p/5463230.html
Copyright © 2011-2022 走看看