I'm very new to Spring MVC and I have one question for you.
I know that tag <mvc:annotation-driven /> handles the annotation such as #Controller, #RequestMapping in a servlet configuration, but I'm using portlets and I am very curious how this annotation works here?
Thx!
It works the same.
If you go with java configuration you'll use:
...
#Configuration
#EnableWebMvc <- (equivalent to <mvc:annotation-driven />)
#ComponentScan(basePackageClasses = { MyConfiguration.class })
...
Or if you go with xml configuration you'll use:
...
<mvc:annotation-driven />
<context:component-scan base-package="package.*" />
...
mvc:annotation-driven is used for enabling the Spring MVC components with its default configurations.
If you dont include mvc:annotation-driven also your MVC application would work if you have used the context:component-scan for creating the beans or defined the beans in your XML file
. But, mvc:annotation-driven does some extra job on configuring the special beans that would not have been configured if you are not using this element in your XML file.
This tag would registers the HandlerMapping and HandlerAdapter required to dispatch requests to your #Controllers. In addition, it also applies some defaults based on what is present in your classpath. Such defaults are:
Using the Spring 3 Type ConversionService as a simpler and more
robust alternative to JavaBeans PropertyEditors
Support for formatting Number fields with #NumberFormat
Support for formatting Date, Calendar, and Joda Time fields with
#DateTimeFormat, if Joda Time is on the classpath
Support for validating #Controller inputs with #Valid, if a JSR-303
Provider is on the classpath
Support for reading and writing XML, if JAXB is on the classpath
Support for reading and writing JSON, if Jackson is on the classpath
context:component-scan element in the spring configuration file would eliminate the need for declaring all the beans in the XML files. Look at the below declaration in your spring configuration file:
<context:component-scan base-package="org.controller"/>
The above declaration in the spring application configuration file would scan the classes inside the specified package and create the beans instance. Note that it could create beans only if that class is annotated with correct annotations. The following are the annotations scanned by this element:
#Component
#Repository
#Service
#Controller
Related
I'm actually studying spring application, more particularly the ComponentScan annotation that scans java packages to find some classes annotated with #Component.
I was wondering if the Spring ComponentScan annotation stores the related components found in other packages inside of the meta-datas of the Main Class (where I have the static void main method?)
Is this the only place where the framework stores these informations?
<context:component-scan base-package="com.mycompany.package" />
tells spring that it should look on com.mycompany.package and find classes annotated with the following (not only #Component ):
#Controller
#Repository
#Service
#Component
Then Spring will register these classes with the bean factory.
the Spring IoC container consumes a form of configuration metadata; this configuration metadata represents how you as an application developer tell the Spring container to instantiate, configure, and assemble the objects in your application.
Configuration metada are either an xml Configuration or java classes annotated with #Configuration that's where spring stores config informations.
I'm a newbie with Spring MVC but now i've been moved to a new project which uses Spring Integration to turn in channel some service. Example in the context.xml
<int:channel id="example-channel" />
<int:service-activator input-channel="example-channel" ref="exampleServiceFacade" />
For every servicefacade i have to bind the service to a channel.
I was wandering, what if I could map the classes to be turned into channels as i could map the beans with component-scan?
<context:component-scan base-package="com.package" />
so i ended up with this tutorial which speaks about some annotation:
#IntegrationComponentScan
But i cannot understand how it's related to the xml tag service activator and channel.. So i'm quite confused. Does anyone with more experience have an idea if what i'm trying to do can be done?
I just want to scan con the classes which defines channels in integration without having to declare every class.
Thanks.
Your question is a bit unclear. Any Spring Integration custom XML tag is parsed by infrastructure and registered as beans in the application context. Like you'd do that via raw <bean>.
#ComponentScan, #Configuration, #Bean and so on are marker annotations to say application context which classes treat as beans.
So, using both techniques for application context configuration you don't lose anything and can continue to mark you class with #Service and use its bean name from <service-activator ref="">.
From other side now you can fully build Spring Integration without any XML! Please, read the mentioned doc in its entirety.
I've been researching what additional capabilities we have when using the mvc:annotation-driven tag and I'm having a difficult time digesting the results, especially in regards to the #Controller annotation. I know this is very similar to this question but please hear me out.
According to the Spring docs
The basic purpose of the #Controller annotation is to act as a stereotype for the annotated class, indicating its role. The dispatcher will scan such annotated classes for mapped methods, detecting #RequestMapping annotations (see the next section).
The documentation then goes on to show that the context:component-scan tag provides this support. So that's all well and good, but then I was looking at what mvc:annotation-driven gives us, and the aforementioned stackoverflow question provides the following answer
mvc:annotation-driven declares explicit support for annotation-driven MVC controllers (i.e. #RequestMapping, #Controller, although support for those is the default behaviour), as well as adding support for declrative validation via #Valid and message body marshalling with #RequestBody/ResponseBody.
This seems kind of redundant to me. Maybe I don't get what this explicit support is. Again, referring back to the official Spring documentation we get the following
[mvc:annotation-driven] registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans that are required for Spring MVC to dispatch requests to #Controllers.
That sounds pretty similar to the last example I provided from the docs. If anyone can provide some examples as to what we can do with the #Controller annotation using only the context:component-scan tag, what some of the limitations are, then the additional functionality of what we get when adding the mvc:annotation-driven tag, I think that would be very helpful. Thanks in advance for any support on this.
Both elements serve an entirely different purpose.
<context:component-scan /> is, as the name implies, for component scanning. It by default scans for all beans with the #Component annotation (or "sub"annotations like #Controller, #Service etc.). It will only register instances of those classes in the application context as beans. That is all.
<mvc:annotation-driven /> is for bootstrapping Spring MVC and it registers, amongst others, a RequestMappingHandlerMapping and RequestMappingHandlerAdapter. The first links requests to a certain method (the #RequestMapping annotation on methods in a #Controller annotated class). The last knows how to execute methods annotated with #RequestMaping.
Now <mvc:annotation-driven /> does nothing for scanning or detecting #Controllers if there are none in the application context then no request mappings are made. Now you have several ways of registering those beans in the application context and one of them is the aforementioned <context:component-scan />.
Basically a #Controller without <mvc:annotation-driven /> is, well, pretty useless as it does nothing but take up memory. It will not be bound to incoming requests, it just hangs around in the application context. It is just another bean like all other beans and nothing special is being done to it. (Recent, but deprecated, versions of Spring register the DefaultAnnotationHandlerMapping which processes the #Controller, this is however deprecated).
The context:component-scan element lists a package that Spring should scan for #Controller annotations (in the base-package attribute).
the mvc:annotation-driven has no such attribute. This is a convenience element that installs a lot of default MVC elements into the application context. These elements are listed in section 16.14.1 of the Spring framework reference. This element does not appear to scan for #Controller annotations.
Contrary to popular belief, there is no dependancy between these elements. An #Controller without mvc:annotation-driven will function without an issue and handle HTTP requests just fine, as long as you have included context:component-scan with an appropriate base-package attribute.
Case 1(annotation-driven)
This is Enabling Spring annotations tag.
All the annotations such as #Controller, #Service, #Autowired etc.. can be used.
This doesn't creates a bean, but find the the annotations, and spring creates corresponding bean for that class if found annotation(such as #Controller, #Service, #Autowired etc..) .
Case 2(component-scan)
Spring will scan the package (and subpackages) of the classes specified in declaration and creates bean for it.
I'm writing web application that uses Spring MVC to bind Spring beans with REST-like channels.
I've created the configuration basic both on my previous apps (pure XML configuration) and example, which used <mvc:annotation-driven/> feature. I'm pointing a package with controllers with <context:component-scan base-package="my.package"/> in spring xml file.
It is working - in Spring 3.0.6.RELEASE. However, after upgrading to 3.1.0.RELEASE my controllers stopped to be detected and no channel was registered. Spring context contains no implementation of HelloChannel interface.
Is this a bug in this Spring version, or I'm using deprecated configuration, which stopped to be supported in newer version? I got no error or warning, simply no bean is auto-detected.
The controller interface definition looks like that:
#RequestMapping("/config") public interface ConfigChannel
And the implementation:
#Controller
public class ConfigChannelImpl implements ConfigChannel
The Spring documentation indicates that interface-based #Controllers are for proxying transactional methods. As such, you are probably using the <tx:annotation-driven /> tag. The problem you now seem to have is that Spring 3.1 introduced support for CGLIB, a runtime-based bytecode manipulator. You need to add proxy-target-class="true" to your transaction configuration and add CGLIB to your classpath.
<tx:annotation-driven proxy-target-class="true" />
From http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping
In case of supporting both XML and annotation, when spring framework do the annotation scan and how to process it?
Could someone give detail scenario?
For XmlWebApplicationContext, it use loadBeanDefinations() via Xml file. But when it do the annotation scan and use which class to process it?
Could explain the detail for ?
Thanks.
Franklin
In an XML based Application Context, annotations are only registered if you explicitly configure that:
<!-- register default annotations (e.g. #Required) -->
<context:annotation-config />
<!-- scan for components in selected package -->
<context:component-scan base-package="org.example"/>
Reference:
Annotation-based container
configuration
Classpath scanning and managed
components
And if you want to check the inner workings, see:
CommonAnnotationBeanPostProcessor
JavaDoc, Source Code
ComponentScanBeanDefinitionParser
JavaDoc, Source Code
I guess u could dig in the sources starting with AnnotationConfigWebApplicationContext.
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.html