Very new to spring and working my way through validation.
I have examples working where I actually implement the spring Validator class, but am working on getting examples working without implementing the Validator class and instead using annotations directly on model class attributes such as #NotBlank and #Email.
My question is this. Is there anyway to make the above scenario (annotations directly on class attributes) work where you are not naming your Controllers after the models that they are implementing?
For example if I had a FormController class and one of the functions inside dealt with adding a user. Is there anyway to Autowire the validation for the User class directly to the Annotations on the the User class or am I stuck writing a UserValidator class and using that.
Have a look at Spring-Roo. I believe they do what you are asking for.
Related
I'm currently on the process of adding Spring and Hibernate to an existing application, but after reading lots of tutorials there are still a couple (aka a lot of things) that either seem strange to me or I'm missing something...
All the tutorials that I found are straight forward ones (like most tutorials should be), as seen on Example A, one controller to handle the requests (JSP or WS) and autowire the manager class to interact with the DB.
In my case this doesn't apply, since the application has a class to handle the requests, then it instantiates a handler class, which in turn creates a new class to handle something else that creates a new class to handle (....)* and then handles the the database connection as seen on Example B.
My question is how can I make my Business logic Class n "Springable", ie, able to make a Database Manager autowired inside of it?
From all the examples that I've seen, I've come up with these alternatives:
Create the autowire to ALL the DbManager inside of the Controller, and then IoC to all the Business Classes until it reaches the Business Logic class n. This would follow with the Spring standards, but would imply the most code refactoring
Transform ALL the Business Logic classes into beans
Add SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); to the Business Logic class n and use the #Autowire to access the DbManager
Am I missing something or is there any other alternative?
This is just my opinion, but you may be interested.
The basic philosophy of Spring, the fact that the creation and configuration of objects involved in the container, but not in the business objects, is known as IoC or Dependency Injection. Based on the configuration, the container creates and associates(injects) the objects with each other. This allows you to remove the code of the business-classes related to instantiation and configuration (this code can be quite complex). So your classes will become easier and cleaner, and can focus on the business-logic and nothing else.
I believe that business objects do not need to create each other. Let Spring do it. He does it perfectly.
Just mark your business logic classes, depend on its role, with one of stereotype: #Component, #Service, #Controller (meaning of stereotypes you can find here), and inject it with #Autowired. And if you need Database Manager in this classes, inject it same way.
So, my choice corresponds to point number two: "2. Transform ALL the Business Logic classes into beans..."
You can (and should!) use Spring Stereotypes for this.
Refer to my previous answer to a similar question for details about the proposed application structure.
I want to implement a feature in which at deploy time, I should load list of objects from Database. The database already have respective implementaiton done which is being used on the fly.
Given that I am new to Spring, I am trying to understand different features of spring which i can leverage to implement this feature. If i wasn't using Spring, I would have
Created a Thread-Safe Singleton Class
Load that class at application load time by servlet life-cycle
Load everything in that Singleton Class and override existing db class to check this singleton class before issuing query. This way a query will be issued only if this class hasn't loaded for some reason.
Now, In spring, I am so confuse. I have been reaidng different articles and trying to find some pointers. First of all, shall i use #Component to make the class singleton ? Would spring take care of thread safety?
Secondly, Would this class be a Service class for spring ? Do i have to annotate it with #Service ?
Third, shall i use #PostConstruct to load this class at startup ? Or there are other better options ?
Here are the answers to your questions:
First of all, shall i use #Component to make the class singleton? Would spring take care of thread safety?
#Component is used for Component Scaning in XML based Spring Configuration to create the Spring Beans. A Bean will create a Singleton Instance of any Class.
Secondly, Would this class be a Service class for spring? Do I have to annotate it with #Service?
#Service is nothing but a Specialization of #Component. It's completely fine if you continue to use #Service or #Repository or replace them with #Component.
Third, shall I use #PostConstruct to load this class at startup? Or there are other better options?
#PostConstruct will run only once after the bean creation. It can be used if you want to load the data from DB to your cache etc. when your application starts for the first time.
As you know when I want to inject a class to my class's property in spring framework I do something like this:
Class sample {
#Autowired
MyService service;
}
or use #Resource or #Named or what else.
but now I wonder that if possible I declare my own annotation like #MyInjection to do this stuff and besides do something more.
for example, instead of searching the application context and find proper bean to inject, create a class and inject this created bean to property of class.
Thanks.
An annotation is just basically data about data. So if you want something to handle your annotation you have to write a custom annotation processor.
I suggest you should look into Spring's AOP features for more details:
Aspect Oriented Programming with Spring
With AOP you basically create an annotation (in your case) then you configure Spring to do something when it bumps into your annotation (Spring uses regexps for this if I remember it right). This is called a Pointcut. Then if Spring finds a match it runs your custom code which can be basically anything.
I think what you want could be achieved by using Spring's factory method, which gets called when Spring is about to resolve some dependency. See example Hope this helps.
I'm currently writing a custom #Cacheable annotation that will take additonal meta-data attributes in addition to those that Spring's #Cacheable provides. However, Spring would need to know how to parse this new annotation. My understanding is that I'd need to extend and override AnnotationCacheOperationSource's determineCacheOperations() so that the new annotation can be parsed with an appropriate CacheableOperation class initialized from it. Is this the correct way to proceed?
Regards,
Steve
Depends.
As per AnnotationCacheOperationSource javadoc,
This class reads Spring's Cacheable, CachePut and CacheEvict
annotations and exposes corresponding caching operation definition to
Spring's cache infrastructure. This class may also serve as base class
for a custom CacheOperationSource.
So if you're asking for yes/no answer if you can extend that class for an extended behaviour of CacheOperationSource, the answer is yes.
However, what determineCacheOperations() method does is that it uses all the available CacheAnnotationParsers. The only default CacheAnnotationParser is SpringCacheAnnotationParser. If you have a custom one, just have another class implementing CacheAnnotationParser for your annotation. Spring should then use it automatically. You can take a look at the SpringCacheAnnotationParser source code to see how they do it.
Edit: ok, I was wrong in that this would happen automatically. My next suggestion is to
implement the interface CacheAnnotationParser, like you apparently already did
extend AnnotationCacheOperationSource so that you put your own CacheAnnotationParser in addition to Spring one in the internal parsers collection
define your custom AnnotationCacheOperationSource to use the same id as Spring one does, so it will override Spring internal. If id matches, it should override Spring one cleanly. This would be something like:
<bean id="annotationCacheOperationSource"
class="com.company.YourCustomAnnotationCacheOperationSource" />
I've following problem, there's a regular spring model (let's call it "A") with some validations-related annotations. Next, there's a command object (regular POJO class that defines some field, one of them is object of type A). The command object implements Validator interface, to make binding and validation work in controller methods.
Question is, how to make use of annotations-configured validations inside the command object (given it implements Validator interface, hence it has supports() and validate() methods).
What I'm trying to achive is to have basic validations on model that is reused and mixed with some heavier business-logic validations in other parts of the system.
I have had the exact same problem. I wanted to use automatic annotation validation for "simple things" and then pass the complex validation logic to my custom spring Validator. But whenever I set the controller validator, all of hibernate's validation stopped working, as described at the end of this tutorial:
http://www.captaindebug.com/2011/07/applying-custom-spring-validator-to.html#.VQR0OI7F-gd
This technique should be used when you need to do ALL your
controller’s validation yourself, and you can’t or don’t want to make
use of the Hibernate’s reference implementation of a JSR 303
validator. From this, you’ll guess that you can’t mix your own custom
Spring validator with Hibernate’s JSR 303 validator. For example,
adding the built-in annotations to the Address command object will
have no effect:
You should forget about old style Spring Validator and delete "setInitBinder()" as described in this related question:
Spring MVC validator annotation + custom validation
You should then only rely on hibernate validation and JSR303.
To add a complex validation to your class (model), say you want to check two date fields - use a custom annotation constraint on class level as described in the link below.
https://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/validator-customconstraints.html#section-class-level-constraints
Hope this helps.
Best Regards,
Alexander
Once look at this may this help you
Using both JSR-303 and Traditional Bean Validation?. There i have given one example for custom validation for model using custom annotation.