1、SpringBoot中使用Servlet
在SpringBootApplication上使用@ServletComponentScan註解後,Servlet、Filter、Listener能夠直接經過@WebServlet、@WebFilter、@WebListener註解自動註冊,無需其餘代碼。html
1.在入口Application類上加入註解@ServletComponentScanjava
package com.hui; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication @ServletComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
2.新建Servlet類,繼承HttpServlet而且加入註解@WebServlet(name=「TestServlet」,urlPatterns="/test")web
package com.hui.qiang; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="TestServlet",urlPatterns="/test") public class TestServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet"); } }
3.以後運行代碼,在瀏覽器地址欄輸入http://localhost:8080/test,若看到控制檯打印doGet,則表示Servlet建立成功。
注意:
(1)若是不加@ServletComponentScan註解則會報404即找不到頁面,控制檯也掃描不到咱們配置的servlet:/test,即沒法被映射
(2)若是Application類和Servlet類不在同一包下,則@ServletComponentScan須要添加相應的路徑,如Application類在包com.hui.xiao下,則寫爲@ServletComponentScan(「com.hui.xiao」)或@ServletComponentScan(「com.hui」)spring
2、Spring, Spring Boot中的@ComponentScan註解用法介紹
@ComponentScan
若是你理解了ComponentScan,你就理解了Spring.
Spring是一個依賴注入(dependency injection)框架。全部的內容都是關於bean的定義及其依賴關係。
定義Spring Beans的第一步是使用正確的註解-@Component或@Service或@Repository.
可是,Spring不知道你定義了某個bean除非它知道從哪裏能夠找到這個bean.
ComponentScan作的事情就是告訴Spring從哪裏找到bean瀏覽器
由你來定義哪些包須要被掃描。一旦你指定了,Spring將會將在被指定的包及其下級的包(sub packages)中尋找bean
下面分別介紹在Spring Boot項目和非Spring Boot項目(如簡單的JSP/Servlet或者Spring MVC應用)中如何定義ComponentScanapp
注:@ComponentScan的不一樣寫法
1.@ComponentScan({「com.xiao.hui」,「com.xiao.qiang」})或@ComponentScan(basePackages = {「com.xiao.hui」,「com.xiao.qiang」})
2.@ComponentScan(「com.xiao」)或@ComponentScan(value = 「com.xiao」)或@ComponentScan(basePackages = { 「com.xiao」 })
3.@ComponentScan(basePackageClasses=要掃描類.class所在位置的包) 意思是要掃描哪一個類所在的包,如@ComponentScan(basePackageClasses=hehe.class),這種寫法不如上面的那種寫法好有侷限性框架
Spring Boot項目
總結:
1.SpringBoot在寫啓動類的時候若是不使用@ComponentScan指明對象掃描範圍,默認指掃描當前啓動類所在的包裏的對象,若是你的其餘包都在使用了@SpringBootApplication註解的主類所在的包及其下級包,則你什麼都不用作,SpringBoot會自動幫你把其餘包都掃描了。爲了方便,我通常都把主類放在了全部類的上一級包中,如項目全部的class文件都放在了包com.beauty的下級包中,則把spring boot的主類放在包com.beauty下。
2.若是當前啓動類沒有包,則在啓動時會報錯:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package錯誤,由於啓動類不能直接放在main/java文件夾下,必需要建一個包把它放進去或者使用@ComponentScan指明要掃描的包。
3.若是你有一些bean所在的包,不在主類的包及其下級包,那麼你須要手動加上@ComponentScan註解並指定那個bean所在的包。ide
舉個栗子,看下面定義的類:測試
package com.xiao.qiang.qianming; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class SpringbootApplication { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(SpringbootApplication.class, args); for (String name : applicationContext.getBeanDefinitionNames()) { System.out.println(name); } } }
類SpringbootApplication在com.xiao.qiang.qianming包下,這個類使用了@SpringBootApplication註解,該註解定義了Spring將自動掃描包com.xiao.qiang.qianming及其子包下的bean
若是你項目中全部的類都定義在上面的包及其子包下,那你不須要作任何事。
但假如你一個類定義在包com.xiao.hui下,則你須要將這個新包也歸入掃描的範圍,有兩個方案能夠達到這個目的。ui
方案1
定義@ComponentScan(「com.xiao」),這麼作掃描的範圍擴大到整個父包com.xiao
@ComponentScan("com.xiao") @SpringBootApplication public class SpringbootIn10StepsApplication {
方案2
定義分別掃描兩個包
@ComponentScan({"com.xiao.hui","com.xiao.qiang"}) @SpringBootApplication public class SpringbootIn10StepsApplication {
非Spring Boot項目
在非Spring Boot項目中,咱們必須顯式地使用@ComponentScan註解定義被掃描的包,能夠經過XML文件在應用上下文中定義或在Java代碼中對應用上下文定義
Java代碼方式:
@ComponentScan({"com.xiao.package1","com.xiao.package2"}) @Configuration public class SpringConfiguration {
注:@Configuration 和@ComponentScan註解背後會作什麼呢?
其實很簡單,@ComponentScan告訴Spring 哪一個packages 的用註解標識的類 會被spring自動掃描而且裝入bean容器。
例如,若是你有個類用@Controller註解標識了,那麼,若是不加上@ComponentScan,自動掃描該controller,那麼該Controller就不會被spring掃描到,更不會裝入spring容器中,所以你配置的這個Controller也沒有意義。
類上的註解@Configuration 是最新的用註解配置spring,也就是說這是個配置文件,和原來xml配置是等效的,只不過如今用java代碼進行配置了 加上一個@Configuration註解就好了,是否是很方便,不須要那麼繁瑣的xml配置了,這樣基於註解的配置,可讀性也大大增高了。
XML文件方式:
<context:component-scan base-package=「com.xiao.package1, com.xiao.package2」 />
3、使用@ComponentScan自動掃描組件實例
包掃描會掃描只要標註了@Controller,@Service,@Repository,@Component這四個註解都會被掃描到容器中。
一、@Controller 控制器(注入服務)
用於標註控制層,至關於struts中的action層
二、@Service 服務(注入dao)
用於標註服務層,主要用來進行業務的邏輯處理
三、@Repository(實現dao訪問)
用於標註數據訪問層,也能夠說用於標註數據訪問組件,即DAO組件.
四、@Component (把普通pojo實例化到spring容器中,至關於配置文件中的<bean id="" class=""/>)
泛指各類組件,就是說當咱們的類不屬於各類歸類的時候(不屬於@Controller、@Services等的時候),咱們就可使用@Component來標註這個類。
案例:<context:component-scan base-package=」com.*」>
上面的這個例子是引入Component組件的例子,其中base-package表示爲須要掃描的全部子包。
有一篇不錯的文章(Spring註解詳解):https://blog.csdn.net/xyh820/article/details/7303330/
新增控制層的java類:TestController和HelloController
import org.springframework.stereotype.Controller; @Controller public class TestController { }
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping(value="/hello", method = RequestMethod.GET) public String hello() { return "Hello, Spring Boot"; } }
新建一個業務邏輯層類:TestService
import org.springframework.stereotype.Service; @Service public class TestService { }
新建一個Person:
public class Person { public Person(String string, int i) { } }
主方法測試:
spring boot:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(value = "com.hui") public class Application { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(Application.class, args); for (String name : applicationContext.getBeanDefinitionNames()) { System.out.println(name); } } }
非spring boot:
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import com.hui.entity.Person; @Configuration @ComponentScan(value = "com.hui") public class ComponentTest { @Bean public Person getPerson() { return new Person("百度好帥", 10000); } public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ComponentTest.class); String[] beanNames = applicationContext.getBeanDefinitionNames(); for (String bean : beanNames) { System.out.println(bean); } } }
運行Application:
控制檯掃描到了/hello,即映射成功
把Application註釋掉運行ComponentTest:
參考:
https://blog.csdn.net/Lamb_IT/article/details/80918704
https://jingyan.baidu.com/article/7908e85cc6930daf481ad2b6.html
————————————————版權聲明:本文爲CSDN博主「小強簽名設計」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/m0_37739193/article/details/85097477