非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");     

   }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM