Почему у spring бина методы toString() и hashCode() дают разные результаты?
Есть класс с аннотацией @RequestScope:
@Component
@RequestScope
public class ComponentRequestScope {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
hashCode() и toString() у него не переопределены.
И есть контроллер, который использует этот класс:
@Controller
public class LoginController {
@Autowired
private ComponentRequestScope component;
@GetMapping("/")
public String loginGet() {
System.out.println(component + " - " + Integer.toHexString(component.hashCode()));
return "login.html";
}
}
Если сделать запрос, то получается такой ответ:
ComponentRequestScope@3be1a523 - 16035cfa
Кроме того, если сделать еще запрос, получается следующий ответ:
ComponentRequestScope@3575d568 - 16035cfa
Почему получается разный хэш при работе не переопределенных методов toString() и hashCode()?
Почему при работе метода hashCode() при двух запросах одинаковый хэш, ведь объекты должны быть разные?
Ответы (1 шт):
Все дело в том, что spring перехватывает выполнение методов toString() и hashCode().
При выполнении метода toString() выполняется метод intercept() класса DynamicAdvisedInterceptor вложенного в класс CglibAopProxy.
При выполнении метода hashCode() выполняется метод intercept() класса HashCodeInterceptor вложенного так же в CglibAopProxy.
Если посмотреть на последний метод:
private static class HashCodeInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public HashCodeInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) {
return CglibAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
}
}
получается что он вычисляет hashCode у класса CglibAopProxy и объекта, полученного из this.advised.getTargetSource(). При этом не используя переданный объект Object proxy (который component).
Следовательно hashCode() зависит от Spring Boot, его классов и объектов, и никак не зависит самого объекта класса ComponentRequestScope.