Spring LDAP 2.0.2 - 无注入(或如何注入) - @Autowired

时间:2014-05-30 00:01:08

标签: spring dependency-injection spring-security spring-ldap

我是Spring LDAP的新手(我使用的版本是:2.0.2),我有一些问题。我正在查询Active Directory。

我要发布我的代码,我的问题在我的主要课程中 - MainLdapTest

ldap_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans     xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ldap="http://www.springframework.org/schema/ldap"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/ldap
                               http://www.springframework.org/schema/ldap/spring-ldap.xsd">

    <!-- Information about this configuration file can be found:
            http://docs.spring.io/spring-ldap/docs/current/reference/#configuration
    -->
    <ldap:context-source id="contextSource"
                         url="ldap://<url>:<port>"
                         base="DC=comp,DC=com"
                         username="<username>"
                         password="<secret>" />

    <ldap:ldap-template id="ldapTemplate" context-source-ref="contextSource" />

    <bean id="LdapUserDAO" class="com.ldap.dao.LdapUserDAOImpl">
        <property name="ldapTemplate" ref="ldapTemplate" />
    </bean>
</beans>

LdapUser.java

@Entry(objectClasses = {"top", "person", "organizationalPerson", "user"})
public final class LdapUser {
    @Id
    private Name distinguishedName;

    @Attribute(name="cn")
    private String cn;

    @Attribute(name="description")
    private String description;

    @Attribute(name="displayName")
    private String displayName;

    @Attribute(name="sAMAccountName")
    private String sAMAccountName;

    @Attribute(name="mail")
    private String mail;

    @Attribute(name="userPrincipalName")
    private String userPrincipalName;

    @Attribute(name="userAccountControl")
    private String userAccountControl;
    // ...
    // getters and setters
    // ...

LdapUserDAO.java

public interface LdapUserDAO
{
    public LdapUser create(LdapUser ldapUser);
    public void update(LdapUser ldapUser);
    public void delete(LdapUser ldapUser);
    public LdapUser findByUid(String uid);
    public List<LdapUser> findAll();
    public List<LdapUser> findByLastName(String lastName);
    public List<LdapUser> findBySAMAccountName(String sAMAccountName);
    public List<LdapUser> findDisabledUsers();
    public List<LdapUser> findDisabledUser(LdapUser ldapUser);
    public List<LdapUser> findByObjectClassPerson();
    public void setLdapTemplate(LdapTemplate ldapTemplate);
}

LdapUserDAOImpl.java

public class LdapUserDAOImpl implements LdapUserDAO
{
    @Autowired
    private LdapTemplate localLdapTemplate;
    // ...
    public List<LdapUser> findBySAMAccountName(String sAMAccountName) {
        return localLdapTemplate.find(query().where("sAMAccountName").is(sAMAccountName), LdapUser.class);
    }
    // ...

MainLdapTest.java

public class MainLdapTest
{
    @Autowired
    private LdapUserDAO ldapUserDao;

    public MainLdapTest() {
        /**
         * The ldap_config.xml above is in my classpath, 
         * but how do I specify that the contents of that file must be used to inject ldapTemplate in this class, or any other class?
         *
         * Below are my tests and their result:
         *
         * Tests
         * 1. This test returns a NullPointerException because ldapTemplate is not set.
         *    Shouldn't it be injected by the "@Autowired" annotation?
         */
        List<LdapUser> queryListError = ldapUserDao.findByObjectClassPerson();
        System.out.println("[ERR] Query returns no values[queryListRetValues]: #[" + queryListError.size() + "]");

        /**
         * 2. As I set the LdapContextSource manually, it returns the data searched in the query.
         *
         *    sAMAccountName is the <username>
         */
        LdapContextSource ctxSrc = new LdapContextSource();
        ctxSrc.setUrl("<url>");
        ctxSrc.setBase("<base>");
        ctxSrc.setUserDn("<username>");
        ctxSrc.setPassword("<password>");
        ctxSrc.afterPropertiesSet();

        ldapUserDao = new LdapUserDAOImpl(ldapTemplate);
        List<LdapUser> queryListRetValues = ldapUserDao.findBySAMAccountName("<username>");
        System.out.println("[OK] Query returns no values[queryListRetValues]: #[" + queryListRetValues.size() + "]");
    }

    public static void main(String[] args)
    {
        MainLdapTest t = new MainLdapTest();
    }
}

实际上,我的代码基于 Spring LDAP - ODM [1] 中的代码。我使用了&#34; @ Autowired&#34; 注释,据我所知,LdapTemplate应该注入我的LdapUserDAOImpl。

我知道这里有一个基本错误,我无法找到。

由于我不确定是否应该只发布链接,但我在春季论坛[2]中提出了同样的问题。

链接: [1-Spring Ldap Reference] [2-Spring Forum Question]

感谢您的关注和帮助。

问候!

2 个答案:

答案 0 :(得分:0)

问题是,任何带有@Autowired注释的对象都需要由Spring创建,以便Spring可以实际注入对象。要使其正常工作,您应该更新为以下内容:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:ldap_config.xml")
public class MainLdapTest
    @Autowired
    private LdapUserDAO ldapUserDao;

    @Test
    public run() {
        /**
         * The ldap_config.xml above is in my classpath, 
         * but how do I specify that the contents of that file must be used to inject ldapTemplate in this class, or any other class?
         *
         * Below are my tests and their result:
         *
         * Tests
         * 1. This test returns a NullPointerException because ldapTemplate is not set.
         *    Shouldn't it be injected by the "@Autowired" annotation?
         */
        List<LdapUser> queryListError = ldapUserDao.findByObjectClassPerson();
        System.out.println("[ERR] Query returns no values[queryListRetValues]: #[" + queryListError.size() + "]");

        /**
         * 2. As I set the LdapContextSource manually, it returns the data searched in the query.
         *
         *    sAMAccountName is the <username>
         */
        LdapContextSource ctxSrc = new LdapContextSource();
        ctxSrc.setUrl("<url>");
        ctxSrc.setBase("<base>");
        ctxSrc.setUserDn("<username>");
        ctxSrc.setPassword("<password>");
        ctxSrc.afterPropertiesSet();

        ldapUserDao = new LdapUserDAOImpl(ldapTemplate);
        List<LdapUser> queryListRetValues = ldapUserDao.findBySAMAccountName("<username>");
        System.out.println("[OK] Query returns no values[queryListRetValues]: #[" + queryListRetValues.size() + "]");
    }
}

这假设ldap_config.xml,junit.jar和spring-test.jar在您的类路径中。

这将有效,因为SpringJunit4ClassRunner将加载您的Spring配置并确保为您注入LdapUserDAO

如果您在标准的Servlet环境中运行,那么您将需要确保Spring在那里创建您的对象。

当然,如果您不想使用Spring的依赖注入,您可以通过以编程方式注入其依赖项来创建LDapUserDAO。

答案 1 :(得分:0)

抱歉关于没有更新/回答的长时间!

答案很简单,为了#34;加载&#34; XML中的bean,您需要这样做:

final ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");

之后,从上下文中获取bean:

LdapProvider ldapProvider = (LdapProvider) context.getBean(LdapProvider.class);

感谢您的帮助!希望它可以帮助别人。