spring 启动时在我的控制器中自动装配一个 Feign 客户端抛出异常
Autowiring a Feign client in my controller when spring launching throws exception
我已经在 and this 上尝试过解决方案,但没有成功,所以我可能遗漏了其他东西
这是我的架构
我有一个受 Oauth2 保护的资源微服务,它正在实现我的业务逻辑,还有一个使用 thymleaf 模板的客户端微服务正在使用该资源。使用 Oauth2RestTemplate 很好,现在我正在尝试使用 feign。
首先是我的资源项目简历
Application.yml
spring.application.name: COMPONENTS
server:
port: 0
eureka.client.service-url.defaultZone: xxxxxxxxxxxxxxxxxxxxxxxx
security.oauth2.resource.token-info-uri: xxxxxxxxxxxxxxxxxxxxxx
security.oauth2.client.client-id: xxxxxxxxxxxxxx
security.oauth2.client.client-secret: xxxxxxxxxxxxx
spring.jackson.date-format: com.fasterxml.jackson.databind.util.ISO8601DateFormat
spring:
datasource:
url: jdbc:mariadb://localhost:3306/pos_auth?createDatabaseIfNotExist=true
username: root
password: xxxxxxxx
driver-class-name: org.mariadb.jdbc.Driver
还有一个简单的控制器
@Controller
@RequestMapping(ApplicationController.API)
public class ApplicationController {
public static final String API = "applications";
@Autowired
private ComponentsService componentsService;
@GetMapping
public ResponseEntity<List<Apps>> getApplicationsList() {
return new ResponseEntity<List<Apps>>(componentsService.getAllApps(), HttpStatus.OK);
}
}
下面是我的客户端Feign客户端实现的重要部分
主要class
@SpringBootApplication
@EnableOAuth2Sso
@EnableEurekaClient
@EnableDiscoveryClient
@EnableWebSecurity
public class ClientApplication extends WebSecurityConfigurerAdapter{
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout()
.logoutSuccessUrl("http://localhost:9999/uaa/exit");
http.authorizeRequests().antMatchers("/graphics/**").permitAll().
and().authorizeRequests().anyRequest().authenticated();
}
@Bean
@LoadBalanced
OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext, OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
@Profile("!cloud")
@Bean
RequestDumperFilter requestDumperFilter() {
return new RequestDumperFilter();
}
}
假配置
@Configuration
@EnableFeignClients
@ImportAutoConfiguration({RibbonAutoConfiguration.class, FeignRibbonClientAutoConfiguration.class, FeignAutoConfiguration.class})
public class FeignConfig {
}
调用索引时客户端控制器中我希望的行为
@Controller
public class MessageController {
@Autowired
OAuth2RestTemplate restTemplate;
@Autowired
private AppClientFeign appClientFeign;
@RequestMapping("/")
String home(Model model) {
model.addAttribute("applications", appClientFeign.getApps());
System.out.println(appClientFeign.getApps());
return "index";
}
}
我的假客户终于来了
@FeignClient("COMPONENTS")
public interface AppClientFeign {
@RequestMapping(method = RequestMethod.GET, value = "/applications")
List<App> getApps();
}
而 运行 客户端我收到以下异常
Field appClientFeign in demo.MessageController required a bean of type
'org.springframework.cloud.netflix.feign.FeignContext' that could not
be found.
- Bean method 'feignContext' not loaded because @ConditionalOnClass did not find required class 'feign.Feign'
解释:
知道 spring 云在默认情况下有 Feign 不添加 feign starter 依赖项不会触发任何编译时间问题(因为使用 javax jpa 应该由入门项目 Data JPA 注入)在我的情况下我忘记添加 starter到项目 pom,spring 搜索他找不到的实现或配置。
解决方法
添加启动器伪装依赖项
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
对于Spring以上的启动版本2.0.0.M4使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
我已经在
这是我的架构
我有一个受 Oauth2 保护的资源微服务,它正在实现我的业务逻辑,还有一个使用 thymleaf 模板的客户端微服务正在使用该资源。使用 Oauth2RestTemplate 很好,现在我正在尝试使用 feign。
首先是我的资源项目简历
Application.yml
spring.application.name: COMPONENTS
server:
port: 0
eureka.client.service-url.defaultZone: xxxxxxxxxxxxxxxxxxxxxxxx
security.oauth2.resource.token-info-uri: xxxxxxxxxxxxxxxxxxxxxx
security.oauth2.client.client-id: xxxxxxxxxxxxxx
security.oauth2.client.client-secret: xxxxxxxxxxxxx
spring.jackson.date-format: com.fasterxml.jackson.databind.util.ISO8601DateFormat
spring:
datasource:
url: jdbc:mariadb://localhost:3306/pos_auth?createDatabaseIfNotExist=true
username: root
password: xxxxxxxx
driver-class-name: org.mariadb.jdbc.Driver
还有一个简单的控制器
@Controller
@RequestMapping(ApplicationController.API)
public class ApplicationController {
public static final String API = "applications";
@Autowired
private ComponentsService componentsService;
@GetMapping
public ResponseEntity<List<Apps>> getApplicationsList() {
return new ResponseEntity<List<Apps>>(componentsService.getAllApps(), HttpStatus.OK);
}
}
下面是我的客户端Feign客户端实现的重要部分
主要class
@SpringBootApplication
@EnableOAuth2Sso
@EnableEurekaClient
@EnableDiscoveryClient
@EnableWebSecurity
public class ClientApplication extends WebSecurityConfigurerAdapter{
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout()
.logoutSuccessUrl("http://localhost:9999/uaa/exit");
http.authorizeRequests().antMatchers("/graphics/**").permitAll().
and().authorizeRequests().anyRequest().authenticated();
}
@Bean
@LoadBalanced
OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext, OAuth2ProtectedResourceDetails details) {
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
@Profile("!cloud")
@Bean
RequestDumperFilter requestDumperFilter() {
return new RequestDumperFilter();
}
}
假配置
@Configuration
@EnableFeignClients
@ImportAutoConfiguration({RibbonAutoConfiguration.class, FeignRibbonClientAutoConfiguration.class, FeignAutoConfiguration.class})
public class FeignConfig {
}
调用索引时客户端控制器中我希望的行为
@Controller
public class MessageController {
@Autowired
OAuth2RestTemplate restTemplate;
@Autowired
private AppClientFeign appClientFeign;
@RequestMapping("/")
String home(Model model) {
model.addAttribute("applications", appClientFeign.getApps());
System.out.println(appClientFeign.getApps());
return "index";
}
}
我的假客户终于来了
@FeignClient("COMPONENTS")
public interface AppClientFeign {
@RequestMapping(method = RequestMethod.GET, value = "/applications")
List<App> getApps();
}
而 运行 客户端我收到以下异常
Field appClientFeign in demo.MessageController required a bean of type 'org.springframework.cloud.netflix.feign.FeignContext' that could not be found.
- Bean method 'feignContext' not loaded because @ConditionalOnClass did not find required class 'feign.Feign'
解释: 知道 spring 云在默认情况下有 Feign 不添加 feign starter 依赖项不会触发任何编译时间问题(因为使用 javax jpa 应该由入门项目 Data JPA 注入)在我的情况下我忘记添加 starter到项目 pom,spring 搜索他找不到的实现或配置。
解决方法 添加启动器伪装依赖项
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
对于Spring以上的启动版本2.0.0.M4使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>