在Servlet init之前调用Spring的afterPropertiesSet?

时间:2014-05-06 06:45:43

标签: java spring java-ee tomcat servlets

我想在tomcat启动后进行一些数据库搜索。

所以我只是实现了InitializingBean并实现了方法afterPropertiesSet并将数据库运行在afterPropertiesSet中。

而且,我的项目正在使用proxool

然后我启动tomcat来测试afterPropertiesSet方法。我收到了这个错误

org.logicalcobwebs.proxool.ProxoolException: Attempt to refer to a unregistered pool by its alias

我认为web.xml

中组件的启动顺序有些问题
<servlet>
    <servlet-name>ServletConfigurator</servlet-name>
    <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
    <init-param>
        <param-name>propertyFile</param-name>
        <param-value>WEB-INF/classes/jdbc.properties</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <servlet-name>ProxoolAdmin</servlet-name>
    <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ProxoolAdmin</servlet-name>
    <url-pattern>/proxool/admin</url-pattern>
</servlet-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:config/application-context-*.xml</param-value>
</context-param>

然后我在afterPropertiesSet方法的第一行设置了一个断点,init org.logicalcobwebs.proxool.configuration.ServletConfigurator方法的第二个断点。

为了避免之前的错误,我只需在afterPropertiesSet中输入一个打印操作。

然后我启动tomcat来检查afterPropertiesSetServletConfigurator的顺序。

afterPropertiesSet init之前调用

ServletConfigurator方法。

我一直在弄清楚为什么会出现Attempt to refer to a unregistered pool by its alias错误。

但是,如何在afterPropertiesSet init之后调用ServletConfigurator

修改

还有班级GoodsRecommendService

@Service
public class GoodsRecommendServiceImpl implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("There is invoked before servlet init!!");
    }
}

2 个答案:

答案 0 :(得分:3)

问题是由在创建上下文的所有ServletContextListener之前调用Servlet的事实引起的。作为ServletContextListener states的API:

  

收到Web应用程序初始化过程正在启动的通知。

     

在初始化Web应用程序中的任何过滤器或servlet之前,会通知所有ServletContextListener上下文初始化。

所以在你的配置中:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:config/application-context-*.xml</param-value>
</context-param>

表示在任何Servlet之前创建Spring ApplicationContext。这就是你收到错误的原因。

要修复它,您需要确保无论您在bean中尝试做什么,都可以在Proxool servlet正确初始化后执行此操作。

我认为最简单的方法是将Spring ApplicationContext切换为DispatcherServlet加载,并确保DispatcherServlet的load-on-startup值大于Proxool servlet的值。

有关DispatcherServlet的更多信息,请参阅here

答案 1 :(得分:0)

另一种方法可能是确保Spring应用程序上下文将配置Proxool,如下例所示:

  <bean id="proxoolProperties" class=" org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="location" value="classpath:proxool.properties"/>
  </bean>

  <bean id="proxoolConfiguration" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
              <property name="targetClass" value="org.logicalcobwebs.proxool.configuration.PropertyConfigurator" />
               <property name="targetMethod" value="configure" />
               <property name="arguments" ref="proxoolProperties" />
  </bean>