1. 程式人生 > 資料庫 >記住我-資料庫版(不重要)⭐⭐⭐出錯啦⭐⭐⭐

記住我-資料庫版(不重要)⭐⭐⭐出錯啦⭐⭐⭐

其實文章:記住我-資料庫版(不重要)步驟思路整個流程啥的沒問題的!

在這裡表揚自己一下程式碼大體思路很清晰。

慢慢的自己敲程式碼的時候就出現了各種錯誤

第一個錯誤: No bean named 'springSecurityFilterChain' available

這是看伺服器日誌發現的錯誤點:

09-Nov-2020 00:49:40.691 嚴重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.filterStart Exception starting filter [springSecurityFilterChain]
 org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' available

我看到的第一眼就知道的是spring的bean沒有配好。但是的確不知道問題出在哪兒了!因為springSecurity我用的是基於註解的配置。按理來說這錯誤bean是被我這個註解配置類給注入進來了呀!一直糾結這個點就讓我有了很多想法:

1. 首先我就回去pom.xml中看看包是不是齊全,然後查看了包是不是衝突導致的。

匯入的包是多少都會存在衝突,依賴優先順序自動會排除衝突。雖然我沒有見過真的依賴衝突。。。

2. 然後我就去看我的spring的配置檔案是不是寫錯了

    <!--配置資料來源:用來連線資料庫的-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/springsecurity_demo?useSSL=false"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    </bean>

    <!--jdbcTemplate:用來操作資料庫的-->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" name="jdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

看完是沒有問題的。

3. 又去看web.xml中是否配置了spring上下文監聽器監聽我這配置檔案

    <!--全域性引數-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--spring上下文物件監聽器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    ...

也是沒問題!甚至考慮到了是不是配置檔名字的問題(不是名字的問題),之前我的配置檔名:spring.xml。然後又改成了applicationContext.xml的。。。

4. 啟動還是報錯,問題就是沒有載入到我這個applicationContext.xml檔案。既然spring-mvc.xml檔案都能載入到為啥我這不能!於是我。。。

把我applicationContext.xml檔案import到spring-mvc.xml檔案中

    <!--註解掃描-->
    <context:component-scan base-package="com.zhoujinyuan.springsecurity"></context:component-scan>
    <!--檢視解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    <!--spring mvc註解驅動-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <mvc:default-servlet-handler/>

    <import resource="applicationContext.xml"></import>

啟動結果好了。臥槽!然後還是不知道問題在哪兒!!!我就可納悶~~~~~

5. 不放棄的我,又去搜了<context-param><init-param>的區別!因為都是指定配置檔案位置的標籤麼~

<context-param>

當伺服器啟動時,伺服器會為每一個WEB應用建立一個唯一的ServletContext物件代表WEB應用。每一個web應用中的servlet共享一個ServletContext,所以Servlet之間就可以通過該物件來實現資料通訊。而這個標籤就是定義在ServletContext域中的引數值,伺服器啟動監聽會將Spring應用上下文物件存到ServletContext域中,共所有的servlet使用。全域性引數!!!

<init-param>

這個卻是Servlet範圍內的引數,只能在Sercvlet的init()的方法中取得。不是全域性的!因為配的是DispatcherServlet!所以在DispatcherServlet的servlet範圍使用。

心得

既然都是spring的配置檔案,我的理解是都可以寫在同一個xml檔案下的!只不過全域性引數的配置載入時機不一樣。早晚的事兒。處於三層架構思想就是各管各的事兒。才有了spring和springmvc配置檔案這一說。不過也讓我學到了不少內容。還有就是自己不太會總結。嘴笨:意思就是給別人講不明白~

6. 言歸正傳,因為我始終堅信一點:我很菜,對於框架和自己寫的程式碼,出了錯,我寧可相信框架也不相信自己寫的程式碼。肯定是我自己哪兒沒寫對!

於是我就參看了和自己仔細理解,慢慢發現原因就是沒有給spring配置檔案加入包掃描

    <!--包掃描-->
    <context:component-scan base-package="com.zhoujinyuan.springsecurity"></context:component-scan>
    ....

我吐了。。。 我發誓:日後只要寫SSM不管三七二十一先開啟包掃描!

第二個錯誤:org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [org.springframework.web.context.ContextLoaderListener]

ContextLoaderListener類出錯

好說:配置沒問題,肯定就是少了導包。

 <!--這個類是spring-web包下的!匯入即可! -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
</dependency>

第三個知識點:關於註解配置類如何在web.xml配置

參看就可

web.xml你需要引導上下文AnnotationConfigWebApplicationContext

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            org.package.YouConfigurationAnnotatedClass
        </param-value>
    </init-param>
</servlet>

並且不要忘了使用@EnableWebMvcMVC註釋。

EDIT as a “comments follow up” => to be Turing Complete:

是的,你當然需要聽眾。儘管以上內容完全回答了“ 如何在Web.xml中註冊Spring @Configuration帶註釋的類而不是applicationContext.xml檔案 ”的問題,但這是Spring官方文件中的一個示例,其佈局完整web.xml

<web-app>
  <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
       instead of the default XmlWebApplicationContext -->
  <context-param>
      <param-name>contextClass</param-name>
      <param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
  </context-param>

  <!-- Configuration locations must consist of one or more comma- or space-delimited
       fully-qualified @Configuration classes. Fully-qualified packages may also be
       specified for component-scanning -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.acme.AppConfig</param-value>
  </context-param>

  <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- Declare a Spring MVC DispatcherServlet as usual -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
           instead of the default XmlWebApplicationContext -->
      <init-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </init-param>
      <!-- Again, config locations must consist of one or more comma- or space-delimited
           and fully-qualified @Configuration classes -->
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.acme.web.MvcConfig</param-value>
      </init-param>
  </servlet>

  <!-- map all requests for /app/* to the dispatcher servlet -->
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/app/*</url-pattern>
  </servlet-mapping>
</web-app>