What's the difference between <mvc:annotation-driven /> and <context:annotation-config /> in servlet? - spring

I am migrating from Spring 2.5 to Spring 3.
They have introduced <mvc:annotation-driven /> which does some black magic. This is expected to be declared in servlet configuration file only.
In Spring 2.5 I have just used <context:annotation-config /> and <context:component-scan base='...'/> tags declared both in application-context.xml and dispatcher servlet configuration XML with appropriate base packages to scan.
So I wonder what is the difference between mvc:annotation-driven and context:annotation-config tags in servlet config and what can I eliminate in Spring 3 config files?

<context:annotation-config> declares support for general annotations such as #Required, #Autowired, #PostConstruct, and so on.
<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 declarative validation via #Valid and message body marshalling with #RequestBody/ResponseBody.

There is also some more detail on the use of <mvc:annotation-driven /> in the Spring docs. In a nutshell, <mvc:annotation-driven /> gives you greater control over the inner workings of Spring MVC. You don't need to use it unless you need one or more of the features outlined in the aforementioned section of the docs.
Also, there are other "annotation-driven" tags available to provide additional functionality in other Spring modules. For example, <transaction:annotation-driven /> enables the use of the #Transaction annotation, <task:annotation-driven /> is required for #Scheduled et al...

mvc:annotation-driven is a tag added in Spring 3.0 which does the following:
Configures the Spring 3 Type ConversionService (alternative to PropertyEditors)
Adds support for formatting Number fields with #NumberFormat
Adds support for formatting Date, Calendar, and Joda Time fields with #DateTimeFormat, if Joda Time is on the classpath
Adds support for validating #Controller inputs with #Valid, if a JSR-303 Provider is on the classpath
Adds support for support for reading and writing XML, if JAXB is on the classpath (HTTP message conversion with #RequestBody/#ResponseBody)
Adds support for reading and writing JSON, if Jackson is o n the classpath (along the same lines as #5)
context:annotation-config
Looks for annotations on beans in the same application context it is defined and declares support for all the general annotations like #Autowired, #Resource, #Required, #PostConstruct etc etc.

Related

Why we use factory-method="aspectOf" in aspect configuration

I found some code in my project.By seeing that i am confused how it scanning the package.we are not mentioning aspect package com.abc.b any where.I have few question
Why aop:aspectj-autoproxy is commentout in xml file?
why is used ?
How com.abc.b package is scanned by spring or there is no need of it or It has link from 'factory-method="aspectOf"'
serviceContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd" default-lazy-init="true">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- <aop:aspectj-autoproxy /> -->
<!-- Enable message logging using the CXF logging feature -->
<cxf:bus>
<!-- <cxf:features>
<cxf:logging/>
</cxf:features> -->
<cxf:inFaultInterceptors>
<bean class="com.flipswap.interceptor.cxf.SafeLoggingInFaultInterceptor"/>
</cxf:inFaultInterceptors>
</cxf:bus>
<context:component-scan base-package="com.abc.service.impl,">
<context:exclude-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
<bean id="eSSyncAspect" class="com.abc.b.ES" factory-method="aspectOf"/>
.
.
.
ES.java
package com.abc.b;
#Aspect
public class ES{
// some code
}
Unless you specify a custom instantiation model, aspects are by default singletons. That means - in case your code is properly woven -, that you can access the singleton instance of the aspect with AspectName.aspectOf().
In order for your classes to be woven by the AspectJ weaver, you need to either use compile-time/build-time weaving or load-time weaving.
In your spring configuration you are telling Spring to configure your aspect as a spring bean by telling how to access the singleton instance (through the static 'factory' method aspectOf). Spring will do the usual configuration (autowiring and any configured post-processors) on the singleton aspect instance.
aop:aspectj-autoproxy is commented out in your configuration because that would conflict with native aspectj support, as it would enable Spring AOP's dynamic proxy based AOP solution, which is very limited compared to native aspectj, and has a different mechanism to configure aspect beans than the one used in your configuration, namely through the static factory method AspectName.aspectOf().
In most cases, AspectJ aspects are singletons, with one instance per class loader. This single instance is responsible for advising multiple object instances.
A Spring IoC container cannot instantiate an aspect, as aspects don't have callable constructors. But it can obtain a reference to an aspect using the static aspectOf() method that AspectJ defines for all aspects, and it can inject dependencies into that aspect.
7.2.1.1. Example
Consider a security aspect, which depends on a security manager. This aspects applies to all changes in the value of the balance instance variable in the Account class. (We couldn't do this in the same way using Spring AOP.)
The AspectJ code for the aspect (one of the Spring/AspectJ samples), is shown below. Note that the dependency on the SecurityManager interface is expressed in a JavaBean property:
public aspect BalanceChangeSecurityAspect {
private SecurityManager securityManager;
public void setSecurityManager(SecurityManager securityManager) {
this.securityManager = securityManager;
}
private pointcut balanceChanged() :
set(int Account.balance);
before() : balanceChanged() {
this.securityManager.checkAuthorizedToModify();
}
We configure this aspect in the same way as an ordinary class. Note that the way in which we set the property reference is identical. Note that we must use the factory-method attribute to specify that we want the aspect "created" using the aspectOf() static method. In fact, this is locating, rather than, creating, the aspect, but the Spring container doesn't care:
<bean id="securityAspect"
class="org.springframework.samples.aspectj.bank.BalanceChangeSecurityAspect"
factory-method="aspectOf">
<property name="securityManager" ref="securityManager"/>
</bean>We don't need to do anything in Spring configuration to target this aspect. It contains the pointcut information in AspectJ code that controls where it applies. Thus it can apply even to objects not managed by the Spring IoC container.

How to configure Bean Validation with Spring MVC

I am trying to configure Spring : LocalValidatorFactoryBean to set my custom TraversableResolver
I do the following in my applicationContext.xml :
<bean id="customTraversableResolver" class="com.package.core.resolver.SimpleTraversableResolver" />
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="traversableResolver" ref="customTraversableResolver" />
</bean>
But at runtime, #Valid bean in controller are validated with default traversable resolver (from hibernate validator).
So, how to configure default bean validation configuration in spring ?
Have you tried adding validation.xml and adding the traversable resolver configuration in there? Btw, what do you want to achieve with your custom resolver?
While you’re using Spring MVC, you must register your validator in this way:
<mvc:annotation-driven validator="validator" />
If you want method-level validation, then define bean:
<!-- Enable method-level validation on annotated methods via JSR-303 -->
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"
p:validatorFactory-ref="validator" />
Then you don’t need validator.xml anymore.
Note: This works with Spring 3.2.x and Hibernate Validator 4.x.

Spring conversion strategy in getBean for JAXB setterless collection

Question
How can I inject a bean containing a list generated by JAXB ?
Detail
These lists have no setters.
You populate them through
getMyList().getList().add(stuff);
For standard java Collections, you usually rely on spring-utils, but Spring does not support these JAXB lists.
Message: no matching editors or conversion strategy found
Context
WSDL-first - CXF server
mock responses are pulled from Spring Application context files
Hints
I'm reluctant to introduce a second JAXB runtime just for the sake of mock response, especially considering this will involve generating a slew of new classes to model my domain objects (i.e. thereby duplicating the objects generated by wsdl2java).
Try creating a Bean for the list:
<bean id="list" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="element1" />
<ref bean="element2" />
</list>
</constructor-arg>
</bean>
Then creating a bean for the inner class using the A$B syntax:
<bean id="myList" class="myPackage.MyOuterClass$MyList" >
<property name="list" ref="list" />
</bean>
Finally the OuterClass Bean:
<bean id="myOuterClass" class="myPackage.MyOuterClass" >
<property name="myList" ref="myList" />
</bean>
My Solution:
I ended up using eclipselink MOXy.
The choice of MOXy was driven by the following characteristics
MOXy allows to declare root elements outside of the classes generated by CXF. So that there is no need to interfere with these classes.
MOXy being a JAXB implementation has no problem dealing with the way JAXB populates lists (without setters).
Remarks:
MOXy XPath support is still weak. I needed to access a specific XML element (a response) out of the total XML file (the list of possible mock responses) and hoped I could unmarshal only a portion of this XML file based on an XPath predicate but this is not supported yet (in 2.5). Support is planned for 2.6.
I did not use any Spring JAXB front-end as a façade for MOXy, as my Mock SEI are already injected through Spring.
Using MOXy proved a pleasant experience and is quite easy to get started with.
I did not experience any collision between MOXy as a JAXB payload jar and the way CXF uses the JDK JAXB implementation for its SOAP layer.

spring basic mvc sample application, annotation scan confusion

Little confused, the basic spring mvc app has this:
app-config.xml
<context:component-scan base-package="org.springframework.samples.mvc.basic" />
and the mvc-config.xml has:
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
Do you really need both?
for component-scan, does this mean if I don't put the correct package path my #Controller and #Service markers will have no effect?
If I need more than one package, do I just duplicate the entry?
I tried using just the mvc:annotation-driven but that didn't work, I had to put com.example.web.controllers in the component-scan xml node to make it work.
context:component-scan is clear
Scans the classpath for annotated components that will be auto-registered as Spring beans. By default, the Spring-provided #Component, #Repository, #Service, and #Controller stereotypes will be detected.
So #Controller is just a Spring bean. Nothing else.
And
mvc:annotation-driven
registers the HandlerMapping and HandlerAdapter required to dispatch requests to your #Controllers
Which is similar to
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
If I need more than one package, do I just duplicate the entry?
You can if you want. context:component-scan is just a bean post-processor.
<context:component-scan base-package="br.com.app.view.controller"/>
<context:component-scan base-package="br.com.app.service"/>
Or
Use a comma-separated list of packages to scan for annotated components.
<context:component-scan base-package="br.com.app.view.controller,br.com.app.service"/>
mvc:annotation-driven allows you to configure behavior of Spring MVC. See details in documentation .For basic usage of Spring MVC you do not need it.
If you need more than one package just mention parent one: <context:component-scan base-package="org.springframework.samples.mvc" />

Wicket with Spring declarative transaction

It is possible to use the Spring Framework's #Transactional support outside of a Spring container. In reference documentation is chapter about AspectJ aspect. I'm trying to use it in my wicket application, but with no positive result.
application-context.xml:
<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" />
<context:annotation-config />
<context:component-scan base-package="com.wicket.app"/>
<context:spring-configured />
<bean id="annotationTransactionAspect" factory-method="aspectOf"
class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
In my form class annotated by #Configurable, I have:
#Transactional
public void process(IFormSubmittingComponent submittingComponent) {
super.process(submittingComponent);
getDao().getEntityManager().flush();
}
Stack trace:
org.apache.openjpa.persistence.TransactionRequiredException: Can only perform operation while a transaction is active.
You might be able to get this working using AspectJ load-time-weaving, but that's a very complex solution for a simple problem.
If you need declarative transactions, then I suggest you move the transactional logic from the wicket component down into a Spring bean, and invoke the Spring bean from the wicket object. The Spring bean would have the transactional annotations, and would be proxied correctly by the Spring container.
I have no experience with Wicket. But is your 'form class' (the one that contains method annotated with #Transactional) Spring managed code? i.e. Who creates the instances of the class?
If it's not, that Spring will not provide #Transactional support (neither will #Autowired work, etc).

Resources