spring basic mvc sample application, annotation scan confusion - spring

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" />

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.

Prevent Spring from meddling with CDI annotations even for factory created instances

I have a legacy product's JAR that contain Spring (4.3.8) managed classes. I need to integrate it with CDI (JavaEE 7).
I have an interface from the legacy JAR, that is implemented by a CDI bean. The CDI bean is requested from the CDI BeanManager and returned from a factory method. The factory method is registered inside Spring XML and works as expected.
The problem occurs, when a Spring bean of the legacy JAR depends on the implemented interface. Spring than injects the CDI implementation instance and scans the class it for known annotations, namingly #Inject. It then tries to resolve the dependency, which doesn't work since the dependency is not available to Spring.
I already tweaked context:property-placeholder excludes, but that changes nothing.
So how can I tell Spring to stop trying to inject something in my factory produced bean instance?
I finally was able to solve (work around) the problem. I had to remove all CDI-Annotations in the legacy JAR (by replacining them with their Spring counterparts), so spring would any longer work.
Then I added the following XML block to the applicationContext.xml of my CDI WAR:
<context:component-scan annotation-config="false" base-package="com.example">
</context:component-scan>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="autowiredAnnotationTypes">
<set>
<value>org.springframework.beans.factory.annotation.Autowired</value>
<value>org.springframework.beans.factory.annotation.Value</value>
</set>
</property>
</bean>
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
<bean class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>org.springframework.beans.factory.annotation.Qualifier</value>
</set>
</property>
</bean>
Basically that drops the support for #Inject, etc. from Spring and leaves it where it belongs: CDI.
It's a bit easier.
AutowiredAnnotationBeanPostProcessor is already a bean, so you can configure it before Spring starts to scan with a ServletContextListener to exclude #Inject annotations. At least from Spring 4.1+, AutowiredAnnotationBeanPostProcessor has a method setAutowiredAnnotationTypes, e.g.:
#WebListener
public class ApplicationConfigListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
ApplicationContext appCtx = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<Class<? extends Annotation>>();
AutowiredAnnotationBeanPostProcessor bean = appCtx.getBean(AutowiredAnnotationBeanPostProcessor.class);
autowiredAnnotationTypes.add(Autowired.class);
autowiredAnnotationTypes.add(Value.class);
bean.setAutowiredAnnotationTypes(autowiredAnnotationTypes);
}
}
You could use a SpringBeanAutowiringInterceptor too.
This is explained here.

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.

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

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.

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