一个诡异的A component required a bean of type异常

目录

1、错误现象:

2、错误场景和条件:

3、错误原因分析:

4、错误解决办法:


1、错误现象:

我的微服务项目中,一个ogarnaization的微服务启动时,出现以下错误:

A component required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.

2、错误场景和条件:

我的微服务的mudule结构如下图:

两个业务类型的微服务,auth和organization子模块的微服务都有装配AuthenticationManager,如下示例:

@RestController
@RequestMapping("/sysmgr/position")
public class PositionController extends BaseController<Position, IPositionService> {

	。。。

	@Resource
	private AuthenticationManager authenticationManager;

     
    。。。
}

这种情况下,启动auth的微服务,一切正常。但是启动organization的微服务,就会出现【A component required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.】错误信息。

另外,测试也发现,两个微服务依赖条件相同,而且如果controller里,都使用了spring security的@PreAuthorize注解,如下。也会出现,一个auth里的鉴权有效,organization里的鉴权无效的情况

	@PreAuthorize("hasAuthority('org:position:user:count')")
	@GetMapping("/getUserCount")
	public FdApiResult getUserCountById(Long id){
		return userFeignService.getUserCountByPositionId(id);
	}

3、错误原因分析:

经过分析发现,两个module的主启动类所在的包,有些差别:

  • auth module的主启动类,在【package com.dev.web
  • organization module的主启动类,在【package com.dev.web.organization
  • commons module所在的包【package com.dev.web.commons

1)为什么auth微服务启动正常?因为【package com.dev.web】在【package com.dev.web.commons】上一级。它的主启动类,启动时,可以将【com.dev.web.commons】下的组件加载到它可访问的容器下。所以,这个微服务一切正常!

2)而,organization微服务的包【package com.dev.web.organization】和【package com.dev.web.commons】同级,它的主启动类,启动时,无法将【package com.dev.web.commons组件加载到它可访问的容器下。所以,这个微服务无法正常加载和调用commons module下的类!

因为启动类上面的@SpringBootApplication里面默认包含了一个@ComponentScan注解,这个注解默认情况下是扫描该类所属包下面的所有类,包含子目录中的类。

4、错误解决办法:

两种方法:

1)修改organization主启动类所在包的位置,改为【package com.dev.web

package com.dev.web;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.stereotype.Component;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800 * 2 )
@MapperScan(basePackages = {"com.freedo.dev.web.organization.**.mapper"})
public class OrgarnizationApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrgarnizationApplication.class,args);
    }
}

2)organization主启动类修改扫描包的范围,确保commons module的包也能被主启动类扫描并加载。修改@SpringBootApplication注解,添加一个参数scanBasePackages ,指定包名为com.dev.web。

@SpringBootApplication(scanBasePackages = {"com.dev.web"})

主启动类的完整代码如下:

@SpringBootApplication(scanBasePackages = {"com.dev.web"})
@EnableDiscoveryClient
@EnableFeignClients
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800 * 2 )
@MapperScan(basePackages = {"com.dev.web.organization.**.mapper"})
public class OrgarnizationApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrgarnizationApplication.class,args);
    }
}

再次测试后,一些正常!

猜你喜欢

转载自blog.csdn.net/louis_lee7812/article/details/127460667