简体   繁体   中英

No access to public method in interface implementation class (access only to method declarated in interface)

I have an interface and two implementations of this interface.

  1. EmailTokenServiceImpl
  2. ResetPasswordTokenServiceImpl

Interface contains only one method named generateToken()

In one of my implementation class ResetPasswordTokenServiceImpl I have added one more method named exampleMethod() .

Now the problem is when I autowired the service having extra method in my controller class I'm not able to call the exampleMethod()

Interface Declaration:

    public interface TokenService {

    /**
     * Generate verification token for given user.
     *
     * @param user the user entity
     * @return the verification token
     */
    public VerificationToken generateToken(User user);
    }

First Service:


    @Service(value = "emailTokenService")
    public class EmailTokenServiceImpl implements TokenService {

    @Value("${email.token.expiration.hours}")
    private int expirationIn;

    /**
     * Generate Token for email verification {@link EmailVerificationToken}
     * @return VerificationToken token
     */
    @Override
    public EmailVerificationToken generateToken(User user) {
        EmailVerificationToken token = new EmailVerificationToken();
        token.setToken(generateHash());
        token.setExpirationDate(getExpirationDate());
        token.setUser(user);
        return token;
    }

Second Service:

    @Service(value = "resetPasswordService")
    public class ResetPasswordTokenServiceImpl implements TokenService {

    @Override
    public ResetPasswordToken generateToken(User user) {
        ResetPasswordToken token = new ResetPasswordToken();
        token.setToken(generateHash());
        token.setExpirationDate(getExpirationDate());
        token.setUser(user);
        return token;
    }

    public String exampleMethod() {
        return "example"; 
    }

Controller (Trying to access the exampleMethod() ):

@RestController
@RequestMapping("/api/auth")
public class SecurityController {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
    private AuthenticationManager authenticationManager;
    private JwtTokenProvider tokenProvider;
    private UserService userService;
    private TokenService resetPasswordService;

    @Autowired
    public SecurityController(
            AuthenticationManager authenticationManager,
            JwtTokenProvider tokenProvider,
            UserService userService,
            TokenService resetPasswordService) {
        this.authenticationManager = authenticationManager;
        this.tokenProvider = tokenProvider;
        this.userService = userService;
        this.resetPasswordService = resetPasswordService;
    }

 @GetMapping("/reset-password/{token}")
    public ResponseEntity<?> resetPasswordRequest(@PathVariable(value = "token") String token) {
      String example = resetPasswordService.exampleMethod();
        return new ResponseEntity<>(HttpStatus.OK);
    }

Why I'm not able to invoke the exampleMethod() method ?

Do I have to declare it in my interface ?

The interface TokenService doesn't declare the method exampleMethod() . So you cannot call that method. You would have to use a cast ((ResetPasswordTokenServiceImpl)resetPasswordService).exampleMethod(); , if resetPasswordService is an instance of ResetPasswordTokenServiceImpl .

If you add that method to the interface, all implementations of TokenService will have to implement that method. For example, EmailTokenServiceImpl doesn't declare that method.

Yes. All your controller knows is that resetPasswordService is an implementation of TokenService .

You could cast resetPasswordService as ResetPasswordTokenServiceImpl but it would be better to instead declare ResetPasswordTokenServiceImpl resetPasswordService explicitly in your constructor.

Don't over-abstract your code. Just explicitly wire in all the necessary implementations of TokenService as their implementing classes. I don't see that there's anything to be gained by treating each different TokenService as instances of the interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM