你该怎么做?当你发现springboot扫描controller没有生效

众所周知springboot扫描controller大概就是这么几种方式

1、扫描的controller和启动类同包,启动类上加上@SpringBootApplication注解

加上@SpringBootApplication为啥就能扫描到,其实我也不知道。那就看下这个注解到底是个啥样的奇葩,它的注解构造了解一下

@Target({ java.lang.annotation.ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {
                org.springframework.boot.context.TypeExcludeFilter.class }),
        @org.springframework.context.annotation.ComponentScan.Filter(type = org.springframework.context.annotation.FilterType.CUSTOM, classes = {
                AutoConfigurationExcludeFilter.class }) })
public @interface SpringBootApplication {
    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
    public abstract Class<?>[] exclude();

    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
    public abstract String[] excludeName();

    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    public abstract String[] scanBasePackages();

    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    public abstract Class<?>[] scanBasePackageClasses();
}

看到没有,它里面有了个@ComponentScan注解,这个注解的作用就是告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器,所以真相大白。也得出一个小知识

@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

大多情况下,自定义的controller和启动类不会在同个包下。这种情况下,要怎么告诉spring这个呆头鹅,有个头上顶着光环(注解)的天使(类)需要它装载。

这时候就可以用

2、启动类加上@ComponentScan(basePackages={"com.xxx.xx"}),basePackages里面填入你需要扫描的类包

万一你这些办法你用也用了,但是发现一点鸟用的没有,想扫描的扫描不到,比如下面的例子。

@Controller
@RequestMapping("/test")
public class HelloController {

    @GetMapping(value = "/say")
    public String sayHello() {

        return "index";
    }
}
@SpringBootApplication
@ComponentScan(basePackages = { "com.demo.auth2.comusmer" })
public class Oauth2ComusmerServer implements ServletContextInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Oauth2ComusmerServer.class, args);
    }

    @Override
    public void onStartup(ServletContext context) throws ServletException {
        context.getSessionCookieConfig().setName("client-session");
    }

}

启动程序并观察一下控制台打印的日志

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v1.5.10.RELEASE)

2018-07-15 08:29:11.509  INFO 1988 --- [           main] c.d.o.comusmer.Oauth2ComusmerServer      : Starting Oauth2ComusmerServer on WINDOWS-2181232 with PID 1988 (F:\wspace\first-oauth2\demo-oauth2-comusmer\target\classes started by Administrator in F:\wspace\first-oauth2\demo-oauth2-comusmer)
2018-07-15 08:29:11.536  INFO 1988 --- [           main] c.d.o.comusmer.Oauth2ComusmerServer      : No active profile set, falling back to default profiles: default
2018-07-15 08:29:12.431  INFO 1988 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@793f29ff: startup date [Sun Jul 15 08:29:12 CST 2018]; root of context hierarchy
2018-07-15 08:29:15.801  INFO 1988 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$448e2a41] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-07-15 08:29:17.418  INFO 1988 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 9001 (http)
2018-07-15 08:29:17.444  INFO 1988 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-07-15 08:29:17.446  INFO 1988 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-07-15 08:29:17.820  INFO 1988 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-07-15 08:29:17.820  INFO 1988 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 5400 ms
2018-07-15 08:29:18.501  INFO 1988 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-07-15 08:29:18.503  INFO 1988 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-07-15 08:29:18.503  INFO 1988 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-07-15 08:29:18.503  INFO 1988 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-07-15 08:29:18.506  INFO 1988 --- [ost-startStop-1] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
2018-07-15 08:29:18.507  INFO 1988 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
Sun Jul 15 08:29:19 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Sun Jul 15 08:29:20 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
2018-07-15 08:29:20.549  INFO 1988 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-07-15 08:29:20.607  INFO 1988 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: default
    ...]
2018-07-15 08:29:21.097  INFO 1988 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2018-07-15 08:29:21.102  INFO 1988 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2018-07-15 08:29:21.106  INFO 1988 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2018-07-15 08:29:21.266  INFO 1988 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-07-15 08:29:21.666  INFO 1988 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2018-07-15 08:29:22.672  INFO 1988 --- [           main] o.h.tool.hbm2ddl.SchemaValidator         : HHH000229: Running schema validator
2018-07-15 08:29:22.879  INFO 1988 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-07-15 08:29:24.571  INFO 1988 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@793f29ff: startup date [Sun Jul 15 08:29:12 CST 2018]; root of context hierarchy
2018-07-15 08:29:24.835  INFO 1988 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-07-15 08:29:24.839  INFO 1988 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-07-15 08:29:24.959  INFO 1988 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-15 08:29:24.966  INFO 1988 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-15 08:29:25.100  INFO 1988 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-07-15 08:29:26.795  INFO 1988 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/css/**'], Ant [pattern='/js/**'], Ant [pattern='/images/**'], Ant [pattern='/webjars/**'], Ant [pattern='/**/favicon.ico'], Ant [pattern='/error']]], []
2018-07-15 08:29:27.067  INFO 1988 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: OrRequestMatcher [requestMatchers=[Ant [pattern='/**']]], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@50ecef36, org.springframework.security.web.context.SecurityContextPersistenceFilter@1669f4e5, org.springframework.security.web.header.HeaderWriterFilter@3d3b4e09, org.springframework.security.web.authentication.logout.LogoutFilter@2c978637, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@6c225adb, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4be1dce6, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@de63949, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@767d9b9, org.springframework.security.web.session.SessionManagementFilter@2520010e, org.springframework.security.web.access.ExceptionTranslationFilter@4fef4f96, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@7b1559f1]
2018-07-15 08:29:27.924  INFO 1988 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-07-15 08:29:28.146  INFO 1988 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 9001 (http)
2018-07-15 08:29:28.213  INFO 1988 --- [           main] c.d.o.comusmer.Oauth2ComusmerServer      : Started Oauth2ComusmerServer in 17.619 seconds (JVM running for 18.688)

很完美有没有,我说的是文字,但是发现没有,日志中并没有/test/say的语句输出。说明HelloController并没有注入成功。

遇到这种情况,要怎么办,是要哭一把呢,还是哭一把呢,毕竟目前的正确姿势都用上了,但是得到却不是想要的。

这时候你该想想技术用法的大方向没错,那么有没有可能是一些细节,比如写入包名写错。经排查确实是包名拼错

修改了正确包名后,启动程序再观察一下控制台

s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3d5c822d: startup date [Sun Jul 15 08:36:39 CST 2018]; root of context hierarchy
2018-07-15 08:36:52.866  INFO 9436 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/test/say],methods=[GET]}" onto public java.lang.String com.demo.oauth2.comusmer.controller.HelloController.sayHello()

控制台很给面子的输出我们想要的东西,因此如果扫描不到,可以考虑下

3、要扫描的类包单词是否正确拼写,要扫描的controller类上是否有加(@Controller或者@RestController注解)

总结

今天写这篇文章,重点不是怎么扫描,这个其实一点都不难,接触过springboot的人基本上都知道怎么用,主要想表达有时候技术问题可能不是真出现在技术用法上,而是一些细节性的非技术问题处理上,比如上面的扫描问题,我这边就是拼写类包时,少了一个字母,导致注入不生效。而因为这个字母,整整花了我一天的时间来排查问题。细节有时候真的可以决定一个事情的成败。。。

原文发布于微信公众号 - Linyb极客之路(gh_c420b2cf6b47)

原文发表时间:2018-07-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Kubernetes

kube-controller-manager最佳配置

kubernetes version: 1.6.2 Kube-controller-manager Configuration kube-controller-...

4719
来自专栏智能计算时代

Designing your SaaS Database for Scale with Postgres

? If you’re building a SaaS application, you probably already have the notion o...

2154
来自专栏运维

U盘安装FreeBSD8.2+Panabit安装配置+Samba文件服务器+DNS缓存服务器

  dd if=FreeBSD-8.2-RELEASE-i386-memstick.img of=/dev/sdb bs=10240 conv=sync 二,安...

1372
来自专栏技术小黑屋

Issues About Installing Octopress

Actually I am fresh to Write Blog with Octopress in Github Pages.According to th...

1102
来自专栏张高兴的博客

张高兴的 Windows 10 IoT 开发笔记:FM 电台模块 KT0803L

3716
来自专栏我的博客

Zend Framework自动加载、简单路由配置(Bootstrap.php)

<?php class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { /* * 自动加...

3418
来自专栏ml

hdu---(2604)Queuing(矩阵快速幂)

Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (...

40711
来自专栏Golang语言社区

Go调试简单的内存泄漏

Memory leaks are a class of bugs where memory is not released even after it is n...

3823
来自专栏全栈架构

Spring Boot 与 Kotlin 上传文件

如果我们做一个小型的web站,而且刚好选择的kotlin 和Spring Boot技术栈,那么上传文件的必不可少了,当然,如果你做一个中大型的web站,那建议你...

983
来自专栏everhad

转载:Package by feature, not layer

The first question in building an application is "How do I divide it up into pac...

1210

扫码关注云+社区