duplication in parsing spring context - spring

Nowadays I've got to know spring mvc.
exactly about
context:component-scan
and
mvc:annotation-driven
and
tx:annotation-driven
in spring config xml
Here is my question.
As I know, "context:component-scan" scans all beans.
and As I heard, mvc:annotation-driven, tx:annotation-driven"s also scan all beans.
I think this is not efficient and not reasonable.
Why scan twice, three times.
Is there any way to avoid this duicate parsing?
Any answer will be appreciated.
Thank you.

In my opinion, scanning process are not twice, three times as you think.
They are declare for related beans I think.
Please refer to below summarize and find out how differences.
<context:annotation-config>
Declares support for general annotations such as #Required, #Autowired, #PostConstruct, and so on.
<context:component-scan>
can also do what <context:annotation-config> does but <context:component-scan> also scans packages to find and register beans within the application context.
<mvc:annotation-driven />
Enables the Spring MVC #Controller programming model and
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.
<tx:annotation-driven />
You do provide the transaction-manager instace directly within element. annotation-config and component-scan won't.

Related

In Spring what is the exact difference between scope="singleton" and singleton="true"

In one interview i have faced this question. In spring configuration file, if we give scope="singleton" what happens and singleton="true" what happens.
Well, in Spring 1.x there were only two scopes, prototype and singleton, so there was only a singleton=true or a singleton=false. Quoting the DTD:
Bean instances can be "singletons" (shared instances) or "prototypes"
(independent instances). Further scopes are supposed to be built on top
of the core BeanFactory infrastructure and are therefore not part of it.
(Source)
However, this did not allow them to introduce other scopes, so they changed the DTD in Spring 2, to scope="singleton" and scope="prototype". This allowed them to introduce other scopes as well, such as scope="session" and scope="request". You can verify this in the DTD of Spring 2 and onwards.
So, to answer your question, normally they should be the same, but in different versions of Spring.

Register Spring filter from BeanDefinitionParser

I am creating a custom namespace for use in the Spring XML configuration. I already implemented a NamespaceHandler and BeanDefinitionParser. So, now I can just put <myns:some-awesome-feature /> into my Spring configuration and it creates the required beans automatically.
In addition to creating some normal Spring beans I would also like to have this annotation register a OncePerRequestFilter to extract some information off of a request for my code to be able to utilize. Is there a way to register a filter programmatically using the two classes I have available when implementing a custom XML tag?
It is not possible without touching web.xml or WebApplicationInitializer, respectively.
But you can create an extendable solution that allows modifications in future without hassle.
Spring Security's <http pattern='...' security="..."/> automatically creates and registers a series of chained filter beans for you. All you have to do is to
register DelegatingFilterProxy in you web.xml and reference springSecurityFilterChain.
You can create a similar solution where you are defining e.g. <myns:awesome-http pattern='...' /> which instantiates OncePerRequestFilter. In web.xml you are declaring a DelegatingFilterProxy which references your awesomeFilterChain. In a future version you can add more filter to your chain without touching the configuration.
I have never implemented such a feature but I'm quite confident that it is possible.
As a starting point take a look at the source of HttpConfigurationBuilder and HttpSecurityBeanDefinitionParser to see how Spring Security implemented <http .../>.

Spring AOP not working on all annotation methods

I have created a custom annotation in my spring mvc project.
The annotation is used to do an AOP
#Around("execution(#Cached * * (..)) && #annotation(cache)")
Here the annotation that I have created is "Cached", any method with the annotation is cached in couch base with the response as its value and the method argument as its key.
The problem is the annotation works (AOP works) on the controllers well. However from controllers, I am making call to different callable classes and utils. When I add the annotation" #Cached" on the callable classes or the util funcations the AOP doesn't work.
In the XML file, the following is what I have declared.
<aop:aspectj-autoproxy/>
<context:spring-configured/>
<context:component-scan base-package="com.abc.xyz">
<!--<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>-->
</context:component-scan>
<bean id="universalController" class="com.abc.xyz.misc.UniversalController"/>
<bean class="com.abc.xyz.api.metric.SystemTiming"/>
<bean class="com.abc.xyz.api.annotations.URLCacheImpl"/>
With Spring AOP, your classes which match the pointcut (where you have placed your #Cached annotation in this specific case) should be Spring beans. So the best guess that I can make is that your utility classes are very likely not Spring beans and that is reason why they are not getting woven in. You have two options that I can think of:
Make your utility classes also clean Spring beans
Use full Aspectj support - this way even though your utility classes are not Spring beans they would be woven with the advice.

Spring custom annotation - how to make it part of a library?

I've created a custom annotation (in Spring 3.05) that works great. I'd like to take that code and make it part of a library, packaged in a jar file, so I don't have to include my custom annotation code in each web app I write.
I'm unable to get Spring to act on the annotation, however. My library jar is in my web app's classpath and I tried scanning for it in applicationContext.xml:
<context:component-scan base-package="my.annotation.pkg" />
The field annotated with my custom annotation continues to be null.
Ideally I'd like to this to just work with a minimum of fuss and configuration, but so far I haven't had any success.
What part of Spring's wiring am I missing to get my custom annotation recognized when it's part of an external library?
Update
Here is how I "solved" it...just had to read a little more closely. In each context file (i.e. applicationContext.xml, dispatch-servlet.xml) I added the line:
<bean class="my.annotation.CustomInjector" />
...where my CustomInjector implements BeanPostProcessor. I based this on the code at this blog post: Implementing Seam style #Logger injection with Spring.
The author says I needed to do exactly what I did, so bad on me for not reading thoroughly. Why, though, is adding that bean definition required? Maybe Spring annotations are configured similarly under the hood - I just don't get why having the jar file on the classpath isn't enough.
Is your custom annotation annotated with the #Component annotation? From the Spring reference manual:
By default, classes annotated with #Component, #Repository, #Service, #Controller, or a custom annotation that itself is annotated with #Component are the only detected candidate components.
Alternatively, you could add a custom include-filter to the component-scan element in your XML configuration.

Different Spring Annotation XML Declarations

There seem to be multiple XML tags for telling Spring to use annotations:
<context:annotation-config/>
<context:component-scan base-package="org.example" />
<mvc:annotation-driven />
<tx:annotation-driven transaction-manager="transactionManager" />
I think the first tag says to scan for annotations, the second says which package to scan (and optionally, can exclude/include what to search for). Then maybe the third says to scan for controller classes. And the last one to scan for data access annotations.
My problem understanding is:
I would think tags 1 and 2 could be combined into one. So I don't know why they are separated.
Tags 3 and 4 seem redundant to 1 and 2.
Could anyone give me a breakdown of what each tag does, and why they're not redundant? And if there are any other annotation XML tags, let me know.
EDIT
After further investigation, I believe I found some additional information:
The <context:annotation-config/> tag allows you to use annotations on variables, constructors, and methods (e.g. #Autowired, #Resource, etc).
The <context:component-scan base-package="org.example" /> tag allows you to use annotations on classes (e.g. #Repository, #Controller, etc).
The <tx:annotation-driven transaction-manager="transactionManager" /> tag actually enables the #Transactional tag (the <context:annotation-config/> tag allowed the #Transactional tag, but it didn't do anything).
Still not completely sure on the <mvc:annotation-driven />. I think maybe it adds further support for JSON, etc.
Difference between annotation-config and component-scan
a) <context:annotation-config/> only looks for annotations on beans in the same application context in which it is defined. This means that, if you put <context:annotation-config/> in a WebApplicationContext for a DispatcherServlet, it only checks for #Autowired beans in your controllers, and not your services. See Section 15.2, “The DispatcherServlet” for more information.
b) Spring provides the capability of automatically detecting 'stereotyped' classes and registering corresponding BeanDefinitions with the ApplicationContext. To autodetect these classes and register the corresponding beans requires the inclusion of the component-scan element in XML where 'basePackage' would be a common parent package (or alternatively a comma-separated list could be specified that included the parent package of each class).
tx:annotation-driven
You do provide the transaction-manager instace directly within element. annotation-config and component-scan won't.
mvc:annotation-driven
This tag registers the DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans that are required for Spring MVC to dispatch requests to #Controllers. The tag configures those two beans with sensible defaults based on what is present in your classpath. Read more at Spring doc.
I would think tags 1 and 2 could be combined into one. So I don't know why they are separated.
For reasons of backwards compatibility. Old Spring apps have to keep working, and merging the tags (which were introduced in different versions of Spring) would break that by changing the default behaviour.
Tags 3 and 4 seem redundant to 1 and 2.
See above. The 4 tags do slightly different, but complimentary things. Yes, if Spring were designed from scratch, there would be fewer of them, but the functionality needs to remain seperate.
To summarise:
<context:annotation-config/> enables annotation support in the context. This was added as part of Java 5 support, at a time when Spring still supported Java 1.4
<context:component-scan base-package="org.example" /> enables automatic scanning and configuration of beans, instead of using explicit declarations. This was added in Spring 2.5.
<mvc:annotation-driven /> is an odd one. It is not required in order to support annotated controller (those work by default). What it does is to actually disable the old style of non-annotated controller, as well as adding support for things like JSON. This is required because older apps still use the older controller style.
<tx:annotation-driven> is required because Spring supports many different styles of transaction demarcation, one of which is the annotation style. This is most popular style, but by no means the only one.

Resources