You'll still have the flexibility to have as many custom validators when they are kept in the Domain layer. The Application layer (the JSF user interface implementation) will have access to all of the custom validators that are held in the domain layer via the ValidatorService.
Remember the Service layer is course grained, meaning that you'll have many methods in each Service implementation.
So, in this case, there will be one CustomValidator interface with many implementations from this:
Interface:
org.myapp.domain.validator.CustomValidator
That implements CustomValidator:
org.myapp.domain.validator.ZipCodeValidator
org.myapp.domain.validator.EmailValidator
org.myapp.domain.validator.DateOfBirthValidator
org.myapp.domain.validator.RegistrationValidator
..
.. and so on...
Then you have a single ValidatorService:
Interface:
org.myapp.service.ValidatorService
that will have the following methods:
abstract void validateZipCode(Object o);
abstract void validateEmail(Object o);
abstract void validateDateOfBirth(Object o);
abstract void validateRegistration(Object o);
..
.. and so on...
That implements ValidatorService:
org.myapp.service.standard.StandardValidatorServic e
As the application grows or requires change in future it is possible to extend the ValidatorService to minimise the interruption between the Application and Domain layers. For example:
Interface:
org.myapp.service.ExtendedValidatorService
that extends from org.myapp.service.ValidatorService interface, and also includes:
abstract void validateAddress(Object o);
abstract void validateUrl(Object o);
..
.. and so on...
That implements ExtendedValidatorService:
org.myapp.service.standard.StandardExtendedValidat orService
Of course, depending on the size of the application it is possible to divide the Services implementation where appropriate (but try keeping it as a few). For example:
OrderValidatorService
RegistrationValidatorService
SupplierValidatorService
Hope this helps.