本文介绍了如何重写Spring框架bean?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想自定义Spring Security提供的OAuth授权服务器的一些代码.负责生成/oauth/authorize的代码是一个名为AuthorizationEndpoint的bean.在AuthorizationServerEndpointsConfiguration类中,以下代码创建AuthorizationEndpoint类的bean:

I want to customize some of the codes of OAuth authorization server provided by spring security. the code responsible for generating /oauth/authorize is a bean named AuthorizationEndpoint. in AuthorizationServerEndpointsConfiguration class the following code creates a bean of AuthorizationEndpoint class:

@Bean
public AuthorizationEndpoint authorizationEndpoint() throws Exception {
    AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint();
    FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
    authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
    authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator());
    authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
    authorizationEndpoint.setTokenGranter(tokenGranter());
    authorizationEndpoint.setClientDetailsService(clientDetailsService);
    authorizationEndpoint.setAuthorizationCodeServices(authorizationCodeServices());
    authorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory());
    authorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator());
    authorizationEndpoint.setUserApprovalHandler(userApprovalHandler());
    return authorizationEndpoint;
}

我想用新的自定义bean覆盖它.我创建了一个扩展AuthorizationEndpoint的类.现在,我已经将相同的代码粘贴到了这个新类中.

I want to override it by a new custom bean. I have created a class which extends AuthorizationEndpoint. for now I have pasted the same code inside this new class.

public class AuthorizationEndpointCustom extends AuthorizationEndpoint {

创建bean:

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Autowired
    AuthorizationServerEndpointsConfiguration asec;


    @Bean
//  @Order(value = Ordered.LOWEST_PRECEDENCE)
    @Primary
    public AuthorizationEndpoint authorizationEndpoint () {

        AuthorizationEndpointCustom authorizationEndpoint = new AuthorizationEndpointCustom();
        FrameworkEndpointHandlerMapping mapping = asec.getEndpointsConfigurer().getFrameworkEndpointHandlerMapping();
        authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access"));
        authorizationEndpoint.setProviderExceptionHandler(asec.getEndpointsConfigurer().getExceptionTranslator());
        authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error"));
        authorizationEndpoint.setTokenGranter(asec.getEndpointsConfigurer().getTokenGranter());
        authorizationEndpoint.setClientDetailsService(clientDetailsService);
        authorizationEndpoint.setAuthorizationCodeServices(asec.getEndpointsConfigurer().getAuthorizationCodeServices());
        authorizationEndpoint.setOAuth2RequestFactory(asec.getEndpointsConfigurer().getOAuth2RequestFactory());
        authorizationEndpoint.setOAuth2RequestValidator(asec.getEndpointsConfigurer().getOAuth2RequestValidator());
        authorizationEndpoint.setUserApprovalHandler(asec.getEndpointsConfigurer().getUserApprovalHandler());

        return authorizationEndpoint;
    }

    private String extractPath(FrameworkEndpointHandlerMapping mapping, String page) {
        String path = mapping.getPath(page);
        if (path.contains(":")) {
            return path;
        }
        return "forward:" + path;
    }

当我尝试创建这个新类的bean时,遇到以下错误:

when I try to create a bean of this new class I encounter the following error:

说明:

bean的"authorizationEndpoint",在 org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration, 无法注册.那个名字的豆子已经被 在类路径资源中定义 [com/example/demo/AuthorizationServerConfig.class]和覆盖是 禁用.

The bean 'authorizationEndpoint', defined in org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration, could not be registered. A bean with that name has already been defined in class path resource [com/example/demo/AuthorizationServerConfig.class] and overriding is disabled.

动作:

考虑重命名其中一个bean或通过设置启用覆盖 spring.main.allow-bean-definition-overriding = true

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

通过将建议的配置添加到application.properties可以消除错误.但是新bean不会替代框架bean.在代码的另一部分中,我从applicationContext访问了AuthorizationEndpoint.我调用了该对象的.getClass(),它与框架中的bean是相同的:

the error goes away by adding the suggested config to application.properties. but the new bean does not replace the framework bean. in another part of my code I accessed the AuthorizationEndpoint from applicationContext. I called the .getClass() of this object and it is the same bean from the framework:

如何强制spring使用我的bean?

how can I force spring to use my bean?

推荐答案

我撰写了一篇有关重写bean的文章,它看起来是如此混乱且不可预测. 在此处阅读最好避免这样做.禁用框架bean的解决方案在于排除创建它的配置类.但这意味着我们必须自己实现漏洞.

I red an article about overriding beans and it seems so messy and unpredictable. read hereit's best to avoid doing so. The solution to disable framework bean lies in excluding the configuration class which creates it. but this means we have to implement the hole thing ourselves.

@SpringBootApplication(exclude=<AuthorizationServerEndpointsConfiguration>.class)

但是覆盖框架端点的解决方案要容易得多.我们要做的就是创建一个具有/oauth/authorize映射的控制器

but the solution to overriding the framework endpoints is much easier.all we have to do is create a controller with mapping for /oauth/authorize

此处了解更多信息.

还有与此主题相关的另一个问题:在此处阅读

there is another question related to this subject: read here

这篇关于如何重写Spring框架bean?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 09:10