我想在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方法的第一行设置一个断点,在initorg.logicalcobwebs.proxool.configuration.ServletConfigurator方法的第二个断点设置。

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

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

afterPropertiesSet初始化之前调用ServletConfigurator方法。

我已经弄清楚了为什么出现Attempt to refer to a unregistered pool by its alias错误。

但是,如何让afterPropertiesSetServletConfigurator初始化之后调用?

编辑

并且有类GoodsRecommendService

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

最佳答案

该问题是由以下事实引起的:在创建上下文的所有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>


意味着您的Spring ApplicationContext是在任何Servlet之前创建的。这就是为什么出现错误的原因。

要解决此问题,您需要确保在bean中尝试执行的任何操作,都必须在Proxool servlet正确初始化后进行。

我认为最简单的方法是切换要由DispatcherServlet加载的Spring ApplicationContext,并确保DispatcherServlet的启动时加载值大于Proxool Servlet的值。

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

07-25 23:53