A weird A component required a bean of type exception

Table of contents

1. Error phenomenon:

2. Error scenarios and conditions:

3. Analysis of error reasons:

4. Error solutions:


1. Error phenomenon:

In my microservice project, when an ogarnaized microservice is started, the following error occurs:

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

2. Error scenarios and conditions:

The module structure of my microservice is as follows:

Two business types of microservices, the microservices of the auth and organization submodules are equipped with AuthenticationManager, as shown in the following example:

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

	。。。

	@Resource
	private AuthenticationManager authenticationManager;

     
    。。。
}

In this case, start the auth microservice and everything will be normal. But when starting the organization's microservices, the error message " A component required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found. " will appear.

In addition, the test also found that the two microservices have the same dependency conditions, and if the controller uses the @PreAuthorize annotation of spring security, as follows. It may also happen that the authentication in an auth is valid but the authentication in the organization is invalid.

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

3. Analysis of error reasons:

After analysis, it was found that there are some differences in the packages where the main startup classes of the two modules are located:

  • The main startup class of auth module is in [ package com.dev.web ]
  • The main startup class of the organization module is in [ package com.dev.web.organization ]
  • The package where the commons module is located [ package com.dev.web.commons ]

1) Why does the auth microservice start normally? Because [ package com.dev.web ] is one level above [ package com.dev.web.commons ]. Its main startup class, when started, can load components under [ com.dev.web.commons ] into the container it can access. So, everything is fine with this microservice!

2) However, the package of the organization microservice [ package com.dev.web.organization ] and [ package com.dev.web.commons ] are at the same level. Its main startup class cannot be [ package com.dev. web.commonsThe component is loaded under the container it can access. Therefore, this microservice cannot load and call classes under the commons module normally!

Because @SpringBootApplication on the startup class contains a @ComponentScan annotation by default, this annotation scans all classes under the package to which the class belongs by default, including classes in subdirectories.

4. Error solutions:

Two methods:

1) Modify the location of the package where the organization's main startup class is located and change it to [ 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) The organization main startup class modifies the scope of scanning packages to ensure that the packages of the commons module can also be scanned and loaded by the main startup class. Modify the @SpringBootApplication annotation, add a parameter scanBasePackages, and specify the package name com.dev.web.

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

The complete code of the main startup class is as follows:

@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);
    }
}

After testing again, some are normal!

Guess you like

Origin blog.csdn.net/louis_lee7812/article/details/127460667