gpt4 book ai didi

java - ThreadLocal 与 Tomcat

转载 作者:行者123 更新时间:2023-11-28 23:12:36 24 4
gpt4 key购买 nike

我有一个带有 ThreadLocal 变量的上下文类,我想用它来存储数据。
LDAPAttributesContextHolder

public class LDAPAttributesContextHolder {

private static final ThreadLocal<List<Attributes>> threadLocalScope = new ThreadLocal<>();

private LDAPAttributesContextHolder() {
throw new IllegalStateException("ThreadLocal context class");
}

public static final List<Attributes> getAttributes() {
return threadLocalScope.get();
}

public static final void setAttributes(List<Attributes> attributes) {
threadLocalScope.set(attributes);
}

public static final void destroy() {
threadLocalScope.remove();
}
}

我使用这个类来存储用户属性并在另一个服务中使用它。
服务1

@Override
public boolean searchInLDAP(String userName, String email) {
LOG.debug("Current thread is {}", Thread.currentThread().getName());
LOG.debug("Start search user with login {} and email {} in LDAP directory", userName, email);
List<Attributes> attributeList = new ArrayList<>();
if(isEmpty(LDAPAttributesContextHolder.getAttributes())) {
attributeList = ldapTemplate.search(query().base("ou=people").where("uid").is(userName).and("mail").is(email),
(AttributesMapper<Attributes>) attributes -> {
if(attributes == null) {
return null;
}
return attributes;
});
LDAPAttributesContextHolder.setAttributes(attributeList);
}
LOG.debug("Status of searching user with login {} and email {} in LDAP is {}", userName, email, (!isEmpty(attributeList)) ? "success" : "failed");
if(nonNull(attributeList) && !isEmpty(attributeList)) {
logAttributes(userName);
}
return nonNull(attributeList) && !isEmpty(attributeList);
}


服务2

public List<String> getAllFacultyGroupNamesByFacultyName() {
String studentFacultyName = "";
LOG.debug("Current thread is {}", Thread.currentThread().getName());
LOG.debug("LDAPContextHolder size {}", LDAPAttributesContextHolder.getAttributes().size());
List<Attributes> attributeList = LDAPAttributesContextHolder.getAttributes();
LOG.debug("In method {} ,Size of attributes is {}", Thread.currentThread().getStackTrace()[0].getMethodName(), attributeList.size());
for(Attributes attributes : attributeList) {
try {
if(attributes.get(FACULTY_ATTRIBUTE) != null &&
attributes.get(ROLE_ATTRIBUTE) != null &&
!attributes.get(ROLE_ATTRIBUTE).get().toString().equals(ORGANIZATIONAL_PERSON)
) {
studentFacultyName = attributes.get(FACULTY_ATTRIBUTE).get().toString();
studentFacultyName = studentFacultyName.contains(IT_FACULTY.toLowerCase()) ? IT_FACULTY : studentFacultyName;
LOG.debug("Student faculty is {}", studentFacultyName);
}
} catch(NamingException e) {
LOG.error("Error while parsing LDAP attributes. {}", e);
}
}

return ...;
}

问题是在第一个方法中线程是 120,但由于某种原因在第二个方法中线程是 115,当我尝试获取上下文时它抛出 NullPointer。
我错过了什么?

最佳答案

ThreadLocal 持有引用 per thread .因此,除非它是按线程初始化的,否则您将获得空指针异常。来自 Javadoc:

These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.

听起来你想要单例模式。由于您使用的是 Spring Boot,因此您可以创建类型为 LDAPAttributesContextHolder 的 bean,并将其 Autowiring 到我们使用的组件/服务中。

关于java - ThreadLocal 与 Tomcat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55401895/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com