Springboot注解@ServletComponentScan和@ComponentS。。
。
⼀、SpringBoot中使⽤Servlet
在SpringBootApplication上使⽤@ServletComponentScan注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解⾃动注册,⽆需其他代码。
1.在⼊⼝Application类上加⼊注解@ServletComponentScan
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")
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");
}
}
⼆、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应⽤)中如何定义ComponentScan
注:@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所在的包。
举个栗⼦,看下⾯定义的类:
package com.xiao.qiang.qianming;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
spring mvc和boot区别import t.ApplicationContext;
import t.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
ApplicationContext applicationContext =
SpringApplication.run(SpringbootApplication.class, args);
for (String name : BeanDefinitionNames()) {
System.out.println(name);
}
}
}
类SpringbootApplication在com.xiao.qiang.qianming包下,这个类使⽤了@SpringBootApplication注解,该注解定义了Spring将⾃动扫描包com.xiao.qiang.qianming及其⼦包下的bean
如果你项⽬中所有的类都定义在上⾯的包及其⼦包下,那你不需要做任何事。
但假如你⼀个类定义在包com.xiao.hui下,则你需要将这个新包也纳⼊扫描的范围,有两个⽅案可以达到这个⽬的。
⽅案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” />
新增控制层的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 t.ApplicationContext;
import t.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 : BeanDefinitionNames()) {
System.out.println(name);
}
}
}
⾮spring boot:
import t.ApplicationContext;
import t.annotation.AnnotationConfigApplicationContext; import t.annotation.Bean;
import t.annotation.ComponentScan;
import t.annotation.Configuration;
import ity.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 = BeanDefinitionNames();
for (String bean : beanNames) {
System.out.println(bean);
}
}
}
运⾏Application:
控制台扫描到了/hello,即映射成功
把Application注释掉运⾏ComponentTest:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论