0

I have a user service. The service has the ability to reset the password.

@Service
public final class UserService {

    private final UserMapper userMapper;

    @Autowired
    public UserService(final UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Transactional
    public String restorePassword(final String loginOrEmail) throws IllegalArgumentException {
        User user = userMapper.findByUsername(loginOrEmail);
        if (user == null) {
            user = userMapper.findByEmail(loginOrEmail);
            if (user == null) throw new IllegalArgumentException("User not found");
        }
        final String newPassword = PasswordGenerator.generate(2, 2, 2, 4);
        returnPasswordAfterRestore(newPassword, user);

        //Later, the password will salt and be encrypted before entering the database.

        userMapper.setPassword(newPassword, user.getUserId());

        return user.getEmail();
    }

    public void returnPasswordAfterRestore(final String password, final User user) {
        System.out.println("------------------------Method run!------------------------");
    }

I need to get the generated password and send it to the user. For this I use Spring AOP.

@Before("execution(* com.example.aop.service.UserService.returnPasswordAfterRestore(..))&&args(password, user)")
    public void beforeReturnPasswordAfterRestore(String password, User user) {
        System.out.println("-------------------------------" + password);
        System.out.println("-------------------------------" + user.getUsername() + " mail:" + user.getEmail());
}

When I make an explicit call to the returnPasswordAfterRestore () method, the aspect fulfills correctly and intercepts the parameters, this confirms the debug mode.

userService.returnPasswordAfterRestore("newPass", user);

But when I make a call to the restorePassword () method, which contains a call to the returnPasswordAfterRestore () method, the aspect does not work.

userService.restorePassword(user.getUsername());

How do I solve this problem? Or how can I get the generated password out of a method without saving it to an external variable?

  • In Spring AOP internal method calls cannot be intercepted. That is the reason the call from restorePassword() to returnPasswordAfterRestore() cannot be adviced. You may either self autowire Userservice bean and use that reference to make the internal call or use pure Aspectj to advice the internal call – R.G May 18 '20 at 16:59
  • Thanks, I'll try to do it. – YellowPhone May 18 '20 at 19:38
  • Do read through the section starting with : *Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are, by definition, not intercepted* in the [reference documentation](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html) – R.G May 19 '20 at 04:49
  • Do you know if I can use the Around annotation to get the result that the method returns? Like AfterReturning (pointcut = "", returning = "retVal"). – YellowPhone May 19 '20 at 08:12
  • Yes . Please go through this [answer](https://stackoverflow.com/a/61765084/4214241) . Then again no internal method call can be advised. – R.G May 19 '20 at 08:15
  • Thank you very much for your help Mr. R.G. I understand that Spring AOP can't advice an internal method call. – YellowPhone May 19 '20 at 15:07

0 Answers0