简体   繁体   English

Spring 引导 2 - 两线 LDAP 模板

[英]Spring Boot 2 - Wire Two LDAP Templates

I need to configure multiple LDAP data sources / LdapTemplates in my Spring Boot 2 application.我需要在我的 Spring Boot 2 应用程序中配置多个 LDAP 数据源/LdapTemplates。 The first LdapTemplate will be used for most of the work, while the second will be used for a once-in-a-while subset of data (housed elsewhere).第一个 LdapTemplate 将用于大部分工作,而第二个将用于偶尔一次的数据子集(位于其他地方)。

I have read these StackOverflow questions regarding doing that, but they seem to be for Spring Boot 1.我已经阅读了有关这样做的 StackOverflow 问题,但它们似乎适用于 Spring Boot 1。
Can a spring ldap repository project access two different ldap directories? spring ldap 存储库项目可以访问两个不同的 ldap 目录吗?
Multiple LDAP repositories with Spring LDAP Repository 多个 LDAP 存储库与 Spring LDAP 存储库

From what I can gather, much of that configuration/setup had to be done anyway, even for just one LDAP data source, back in Spring Boot 1. With Spring Boot 2, I just put the properties in my config file like so据我所知,无论如何都必须完成大部分配置/设置,即使只有一个 LDAP 数据源,回到 Spring 引导 1。使用 Spring 引导 2,我只需将属性放入 myconfig 文件 2,

ldap.url=ldap://server.domain.com:389
ldap.base:DC=domain,DC=com
ldap.username:domain\ldap.svc.acct
ldap.password:secret

and autowire the template in my repository like so并像这样在我的存储库中自动装配模板

@Autowired
private final LdapTemplate ldapTemplate;

and I'm good to go.我对 go 很好。 (See: https://stackoverflow.com/a/53474188/3669288 ) (见: https://stackoverflow.com/a/53474188/3669288

For a second LDAP data source, can I just add the properties and configuration elements for "ldap2" and be done (see linked questions)?对于第二个 LDAP 数据源,我是否可以只添加“ldap2”的属性和配置元素并完成(请参阅链接问题)? Or does adding this configuration cause Spring Boot 2's auto configuration to think I'm overriding it and so now I lose my first LdapTemplate, meaning I now need to go explicitly configure that as well?或者添加此配置是否会导致 Spring Boot 2 的自动配置认为我正在覆盖它,所以现在我丢失了我的第一个 LdapTemplate,这意味着我现在需要 go 显式配置它?
If so, do I need to configure everything, or will only a partial configuration work?如果是这样,我需要配置所有内容,还是仅部分配置有效? For example, if I add the context source configuration and mark it as @Primary (does that work for LDAP data sources?), can I skip explicitly assigning it to the first LdapTemplate?例如,如果我添加上下文源配置并将其标记为@Primary (这适用于 LDAP 数据源吗?),我可以跳过将其显式分配给第一个 LdapTemplate 吗? On a related note, do I still need to add the @EnableLdapRepositories annotation, which is otherwise autoconfigured by Spring Boot 2?在相关说明中,我是否还需要添加@EnableLdapRepositories注释,否则它会由 Spring Boot 2 自动配置?

TLDR : What's the minimum configuration I need to add in Spring Boot 2 to wire in a second LdapTemplate? TLDR :我需要在 Spring Boot 2 中添加什么以连接第二个 LdapTemplate 的最低配置是什么?

This takes what I've learned over the weekend and applies it as an answer to my own question.这需要我在周末学到的知识,并将其作为我自己问题的答案。 I'm still not an expert in this so I welcome more experienced answers or comments.我仍然不是这方面的专家,所以我欢迎更有经验的答案或评论。

The Explanation说明

First, I still don't know for certain if I need the @EnableLdapRepositories annotation.首先,我仍然不确定是否需要@EnableLdapRepositories注释。 I don't yet make use of those features, so I can't say if not having it matters, or if Spring Boot 2 is still taking care of that automatically.我还没有使用这些功能,所以我不能说它是否重要,或者 Spring Boot 2 是否仍在自动处理这些问题。 I suspect Spring Boot 2 is, but I'm not certain.我怀疑 Spring Boot 2 是,但我不确定。

Second, Spring Boot's autoconfigurations all happen after any user configurations, such as my code configuring a second LDAP data source.其次,Spring 引导的自动配置都发生在任何用户配置之后,例如我的代码配置了第二个 LDAP 数据源。 The autoconfiguration is using a couple of conditional annotations for whether or not it runs, based on the existence of a context source or an LdapTemplate.根据上下文源或 LdapTemplate 的存在,自动配置使用几个条件注释来确定它是否运行。
This means that it sees my "second" LDAP context source (the condition is just that a context source bean exists, regardless of what its name is or what properties it is using) and skips creating one itself, meaning that I no longer have that piece of my primary data source configured.这意味着它看到了我的“第二个”LDAP 上下文源(条件是上下文源 bean 存在,不管它的名称是什么或它使用什么属性)并跳过自己创建一个,这意味着我不再拥有它配置了我的主要数据源。
It will also see my "second" LdapTemplate (again, the condition is just that an LdapTemplate bean exists, regardless of what its name is or what context source or properties it is using) and skip creating one itself, so I again no longer have that piece of my primary data source configured.它还将看到我的“第二个”LdapTemplate(同样,条件只是存在一个 LdapTemplate bean,无论它的名称是什么,或者它正在使用什么上下文源或属性)并跳过自己创建一个,所以我不再有我配置的主要数据源的那部分。
Unfortunately, those conditions mean that in this case there is no in-between either (where I can manually configure the context source, for example, and then allow the autoconfiguration of the LdapTemplate to still happen).不幸的是,这些条件意味着在这种情况下,两者都没有中间(例如,我可以手动配置上下文源,然后允许 LdapTemplate 的自动配置仍然发生)。 So the solution is to either make my configuration run after the autoconfiguration, or to not leverage the autoconfiguration at all and set them both up myself.所以解决方案是让我的配置在自动配置之后运行,或者根本不利用自动配置并自己设置它们。

As for making my configuration run after the autoconfiguration: the only way to do that is to make my configuration an autoconfiguration itself and specify its order to be after Spring's built-in autoconfiguration (see: https://stackoverflow.com/a/53474188/3669288 ).至于让我的配置在自动配置之后运行:唯一的方法是让我的配置本身成为自动配置并指定它的顺序在 Spring 的内置自动配置之后(参见: https://stackoverflow.com/a/53474188 /3669288 )。 That's not appropriate for my use case, so for my situation (because Spring Boot's setup does make sense for a standard single-source situation) I'm stuck forgoing the autoconfiguration and setting them both up myself.这不适合我的用例,所以对于我的情况(因为 Spring Boot 的设置对于标准的单源情况确实有意义)我坚持放弃自动配置并自己设置它们。

The Code编码

Setting up two data sources is pretty well covered in the following two answers (though partly for other reasons), as linked in my question, but I'll also detail my setup here.如我的问题中所链接的,以下两个答案(尽管部分出于其他原因)很好地涵盖了设置两个数据源,但我还将在此处详细说明我的设置。
Can a spring ldap repository project access two different ldap directories? spring ldap 存储库项目可以访问两个不同的 ldap 目录吗?
Multiple LDAP repositories with Spring LDAP Repository 多个 LDAP 存储库与 Spring LDAP 存储库

First up, the configuration class needs to be created, as one was not previously needed at all with Spring Boot 2. Again, I left out the @EnableLdapRepositories annotation partly because I don't use it yet, and partly because I think Spring Boot 2 will still cover that for me.首先,需要创建配置 class,因为之前 Spring Boot 2 根本不需要配置。同样,我省略了@EnableLdapRepositories注释,部分原因是我还没有使用它,部分原因是我认为 Z318008DD81C2F4D7985ECF6E0CE8AF1D1Z Boot 2 2仍然会为我覆盖。 (Note: All of this code was typed up in the Stack Overflow answer box as I don't have a development environment where I'm writing this, so imports are skipped and the code may not be perfectly compilable and function correctly, though I hope it's good.) (注意:所有这些代码都是在 Stack Overflow 答案框中输入的,因为我没有编写此代码的开发环境,因此跳过了导入,并且代码可能无法完美编译并且 function 正确,尽管我希望它是好的。)

@Configuration
public class LdapConfiguration {
}

Second is manually configuring the primary data source;二是手动配置主数据源; the one that used to be autoconfigured but no longer will be.曾经被自动配置但不再是的那个。 There is one piece of Spring Boot's autoconfiguration that can be leveraged here, and that is its reading in of the standard spring.ldap.* properties (into a properties object), but since it wasn't given a name, you have to reference it by its fully qualified class name.有一个 Spring Boot 的自动配置可以在这里使用,那就是它读取标准spring.ldap.* ,但因为它不是属性的引用。它以其完全限定的 class 名称命名。 This means you can skip straight to setting up the context source for the primary data source.这意味着您可以直接跳到为主数据源设置上下文源。 This code is not quite as full featured as the actual autoconfiguration code (See: Spring Code ) I marked this LdapTemplate as @Primary because for my use, this is the primary data source and so it's what all other autowired calls should default to.此代码不像实际的自动配置代码那样功能齐全(请参阅: Spring 代码)我将此@Primary标记为 @Primary,因为对于我的使用,这是主要数据源,因此它是所有其他自动装配调用的默认值。 This also means you don't need a @Qualifier where you autowire this source up (as seen later).这也意味着您不需要@Qualifier来自动连接此源(如稍后所见)。

@Configuration
public class LdapConfiguration {
    @Bean(name="contextSource")
    public LdapContextSource ldapContextSource(@Qualifier("spring.ldap-org.springframework.boot.autoconfigure.ldap.LdapProperties") LdapProperties properties) {
        LdapContextSource source = new LdapContextSource();
        source.setUrls(properties.getUrls());
        source.setUserDn(properties.getUsername());
        source.setPassword(properties.getPassword());
        source.setBaseEnvironmentProperties(Collections.unmodifiableMap(properties.getBaseEnvironment()));
        
        return source;
    }
    
    @Bean(name="ldapTemplate")
    @Primary
    public LdapTemplate ldapTemplate(@Qualifier("contextSource") LdapContextSource source) {
        return new LdapTemplate(source);
    }
}

Third is to manually configure the secondary data source, the one that caused all of this to begin with.第三是手动配置辅助数据源,这是导致所有这一切的开始。 For this one, you do need to configure the reading of your properties into an LdapProperties object.对于这个,您确实需要将属性读取配置到 LdapProperties object 中。 This code builds on the previous code, so you can see the complete class for context.此代码基于前面的代码构建,因此您可以查看完整的 class 上下文。

@Configuration
public class LdapConfiguration {
    @Bean(name="contextSource")
    public LdapContextSource ldapContextSource(@Qualifier("spring.ldap-org.springframework.boot.autoconfigure.ldap.LdapProperties") LdapProperties properties) {
        LdapContextSource source = new LdapContextSource();
        source.setUrls(properties.getUrls());
        source.setUserDn(properties.getUsername());
        source.setPassword(properties.getPassword());
        source.setBaseEnvironmentProperties(Collections.unmodifiableMap(properties.getBaseEnvironment()));
        
        return source;
    }
    
    @Bean(name="ldapTemplate")
    @Primary
    public LdapTemplate ldapTemplate(@Qualifier("contextSource") LdapContextSource source) {
        return new LdapTemplate(source);
    }
    
    
    
    @Bean(name="ldapProperties2")
    @ConfigurationProperties("app.ldap2")
    public LdapProperties ldapProperties2() {
        return new LdapProperties();
    }
    
    @Bean(name="contextSource2")
    public LdapContextSource ldapContextSource2(@Qualifier("ldapProperties2") LdapProperties properties) {
        LdapContextSource source = new LdapContextSource();
        source.setUrls(properties.getUrls());
        source.setUserDn(properties.getUsername());
        source.setPassword(properties.getPassword());
        source.setBaseEnvironmentProperties(Collections.unmodifiableMap(properties.getBaseEnvironment()));
        
        return source;
    }
    
    @Bean(name="ldapTemplate2")
    public LdapTemplate ldapTemplate2(@Qualifier("contextSource2") LdapContextSource source) {
        return new LdapTemplate(source);
    }
}

Finally, in your class that uses these LdapTemplates, you can autowire them as normal.最后,在使用这些 LdapTemplates 的 class 中,您可以照常自动装配它们。 This uses constructor autowiring instead of the field autowiring the other two answers used.这使用构造函数自动装配而不是字段自动装配使用的其他两个答案。 Either is technically valid though constructor autowiring is recommended.尽管建议使用构造函数自动装配,但两者在技术上都是有效的。

@Component
public class LdapProcessing {
    protected LdapTemplate ldapTemplate;
    protected LdapTemplate ldapTemplate2;
    
    @Autowired
    public LdapProcessing(LdapTemplate ldapTemplate, @Qualifier("ldapTemplate2") LdapTemplate ldapTemplate2) {
        this.ldapTemplate = ldapTemplate;
        this.ldapTemplate2 = ldapTemplate2;
    }
}

TLDR : Defining a "second" LDAP data source stops the autoconfiguration of the first LDAP data source, so both must be (nearly fully) manually configured if using more than one; TLDR :定义“第二个”LDAP 数据源会停止第一个 LDAP 数据源的自动配置,因此如果使用多个数据源,则必须(几乎完全)手动配置两者; Spring's autoconfiguration can not be leveraged even for the first LDAP data source.即使对于第一个 LDAP 数据源,也无法利用 Spring 的自动配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM