Spring framework annotation question - java

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

Related

Spring Mail with Freemarker Templates from Database

I am a newbie to adding Freemarker to Spring and Spring Mail. I am not using Spring Boot, but I am using the latest Spring 4.x, and though we have an application context XML file, we do use annotations.
So, ultimately I want to read the templates out of a database, because we may have many of them for many clients. We will not be loading templates from a filename or from disk.
We have our Spring Application as a maven multi-module project:
entity.jar - module
dao.jar - module
services.jar - module
ws.jar - module
Under services we have an application context file that defines Freemarker as follow:
<bean id="freemarkerConfiguration"
class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="preTemplateLoaders">
<list>
<ref bean="databaseTemplateLoader" />
</list>
</property>
</bean>
<bean name="databaseTemplateLoader"
class="com.myapp.server.util.DatabaseToFreeMarkerTemplateLoader" />
I have a new class called:
public class DatabaseToFreeMarkerTemplateLoader extends StringTemplateLoader
{
// todo: add code here
}
But I am not sure what else I need in here. I am looking on the internet for some examples, but I can't find too much.
If someone can point me to an example, or refer me to another link here, I'll do my best to see if I can literally fill in the blanks.
Thanks!
BTW: I am surprised I had to include spring-web in my services layer in order to make this work. I just wanted to format an email and not html pages. So if there a better formatting tool that works seamlessly with Spring, let me know.
I don't know this part of Spring much, but I don't think you need spring-web. You could just use the FreeMarker API directly both for configuring (i.e., create a freemarker.template.Configuration singleton bean) and generating the output (template = configuration.getTemplate(...), template.process(...)). Finally you simply use message.setText(theOutputFromTemplateDotProcess, true); (where message is the Spring MimeMessageHelper). So there's no much to integrate with Spring here, I believe. (Even if someone needs to load templates from Spring resources, they can use an org.springframework.ui.freemarker.SpringTemplateLoader via Configuration.setTemplateLoader.)
As of using FreeMarker API directly (not related to Spring), see this example: http://freemarker.org/docs/pgui_quickstart_all.html

MVC Annotation Spring MVC <mvc:annotation-driven />

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

spring integration and component scan

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.

Spring support for #Controller given by <context:component-scan /> vs <mvc:annotation-driven>

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.

Spring JPA Exception Translation

I have configured my application context as stated in the spring documentation to enable Exception Translation from jpa exceptions to spring DataAccessException. Should I also provide the implementation of PersistenceExceptionTranslator? If so, can anyone give me an example of how this is done?
I do it only by putting the #Repository annotation on my DAO or Manager class that uses the EntityManager.
Make sure that you enabled component scanning:
<context:component-scan base-package="org.example"/>
You can enable exception translation as well as repository scan by using following xml configuration
<jpa:repositories base-package="com.nagarro.ncpp.backend.repository" />

Categories