記住我-資料庫版(不重要)⭐⭐⭐出錯啦⭐⭐⭐
其實文章:記住我-資料庫版(不重要)步驟思路整個流程啥的沒問題的!
在這裡表揚自己一下程式碼大體思路很清晰。
慢慢的自己敲程式碼的時候就出現了各種錯誤
第一個錯誤: 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>