Java 通过注释而不是 XML 配置 Spring LdapTemplate 的最佳实践?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25515345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:33:07  来源:igfitidea点击:

Best practice for configuring Spring LdapTemplate via annotations instead of XML?

javaspring-bootannotationsspring-ldap

提问by Tim

For a Spring Boot application, I successfully configured a Spring LdapTemplateusing annotations, including the LdapContextSourcedependency with @Values from application.properties. (Woot! I couldn't find an example, so maybe this will help others.)

对于 Spring Boot 应用程序,我LdapTemplate使用annotations成功配置了 Spring ,包括LdapContextSource@Valueapplication.properties 中的 s的依赖关系。(哇!我找不到例子,所以也许这会帮助其他人。)

The snippets (below) setup the context source, inject it into an LdapTemplate, and autowire that into my DirectoryService.

片段(如下)设置上下文源,将其注入LdapTemplate,然后将其自动装配到我的 DirectoryService 中。

Is there a better/cleaner way to setup the ContextSourcein a Spring Boot app?

有没有更好/更干净的方法来设置ContextSourceSpring Boot 应用程序?

application.properties (on the classpath):

application.properties(在类路径上):

ldap.url=ldap://server.domain.com:389
ldap.base:OU=Employees,OU=Users,DC=domain,DC=com
ldap.username:CN=myuserid,OU=employees,OU=Users,DC=domain,DC=com
ldap.password:secretthingy

MyLdapContextSource.java :

MyLdapContextSource.java :

@Component
public class MyLdapContextSource extends LdapContextSource implements ContextSource {

    @Value("${ldap.url}")
    @Override
    public void setUrl(String url) { super.setUrl(url);  }

    @Value("${ldap.base}")
    @Override
    public void setBase(String base) {super.setBase(base); }

    @Value("${ldap.username}")
    @Override
    public void setUserDn(String userDn) {super.setUserDn(userDn); }

    @Value("${ldap.password}")
    @Override
    public void setPassword(String password) { super.setPassword(password); }
}

MyLdapTemplate.java:

MyLdapTemplate.java:

@Component
public class MyLdapTemplate extends LdapTemplate {

    @Autowired
    public MyLdapTemplate(ContextSource contextSource) { super(contextSource); }
}

DirectoryService.java:

目录服务.java:

@Service
public class DirectoryService {

    private final LdapTemplate ldapTemplate;

    @Value("${ldap.base}")
    private String BASE_DN;

    @Autowired
    public DirectoryService(LdapTemplate ldapTemplate) { this.ldapTemplate = ldapTemplate; }

    public Person lookupPerson(String username) {
        return (Person) ldapTemplate.lookup("cn=" + username, new PersonAttributesMapper());
    }

    public List<Person> searchDirectory(String searchterm) {
        SearchControls searchControls = new SearchControls();
        searchControls.setCountLimit(25);
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

        List<Person> people = (List<Person>) ldapTemplate.search(
                BASE_DN, "cn=" + searchterm, searchControls, new PersonAttributesMapper());
        return people;
    }
}

采纳答案by M. Deinum

Why all the subclasses? Just use configuration to configure the beans. Either XML or Java Config.

为什么是所有的子类?只需使用配置来配置bean。XML 或 Java 配置。

@Configuration
public class LdapConfiguration {

    @Autowired
    Environment env;

    @Bean
    public LdapContextSource contextSource () {
        LdapContextSource contextSource= new LdapContextSource();
        contextSource.setUrl(env.getRequiredProperty("ldap.url"));
        contextSource.setBase(env.getRequiredProperty("ldap.base"));
        contextSource.setUserDn(env.getRequiredProperty("ldap.user"));
        contextSource.setPassword(env.getRequiredProperty("ldap.password"));
        return contextSource;
    }

    @Bean
    public LdapTemplate ldapTemplate() {
        return new LdapTemplate(contextSource());        
    }

}

Your DirectoryServicecan remain the same as it will have the LdapTemplateautowired.

DirectoryService可以保持不变,因为它将LdapTemplate自动装配。

A general rule of thumb is that you don't want to extend your infrastructure beans (like DataSourceor LdapTemplate) but configure them explicitly. This as opposed to your application beans (services, repositories etc.).

一般的经验法则是,您不想扩展您的基础设施 bean(如DataSourceLdapTemplate),而是明确地配置它们。这与您的应用程序 bean(服务、存储库等)相反。

回答by xlm

Explicit wiring up of your LDAP isn't necessary at all for straight forward cases. This is the sort of thing Spring Boot aims to eliminate by being opinionated in the first place.

对于直截了当的情况,根本不需要显式连接 LDAP。这是 Spring Boot 旨在通过自以为是首先消除的那种事情。

Ensure you have the spring-boot-starter-data-ldapor the spring-ldap-coredependency included, e.g. for Maven in your pom:xml:

确保您包含spring-boot-starter-data-ldapspring-ldap-core依赖项,例如在您的 Maven 中pom:xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>

Configure your LDAP in application.propertieswith the following keys:

application.properties使用以下键配置您的 LDAP :

# Note the spring prefix for each and use just the CN for username
spring.ldap.url=ldap://server.domain.com:389
spring.ldap.base=OU=Employees,OU=Users,DC=domain,DC=com
spring.ldap.username=myuserid
spring.ldap.password=secretthingy

Then simply rely on Spring to autowire, e.g. using field injection1:

然后简单地依靠 Spring 自动装配,例如使用字段注入1

@Autowired
private final LdapTemplate ldapTemplate;

Reference: Spring Boot Reference Guide: LDAP

参考:Spring Boot 参考指南:LDAP



1Field injection is generally not recommendedbut it's used here for concision.

1通常不推荐使用字段注入,但为了简洁起见,这里使用它。