Both #Component and #Named for the same bean class - java

Does a class which will act as a bean in a Spring application require both #Component and #Named at the same time?
What is the significance if both are used so?
I tried searching the net as well as saw the standard documentation of these annotations and found them a bit confusing.
Finally which name is taken by the application if the #Named annotation does not specify any name for the bean?

#Component and #Named are annotations that basically do the same thing, but come from different APIs.
#Component belongs to Spring API. It marks class to be autodetected as a bean and optionally allows you to specify a name for that bean (#Component("foo")). Without explicit name specification detected bean will get a default name derived from the name of its class.
#Named belongs to javax.inject API. It marks class to be autodetected as a bean and requires you to specify a name.
Spring supports both these APIs. It doesn't make sense to use both annotations at the same class since they provide the same functionality.
See also:
3.10 Classpath scanning and managed components

Spring supports #Named annotation (JSR-330) as an alternative to #Component (Spring).
Generally, #Named is poorly named since doesn't describe what it does, so I would prefer to use #Component whenever I can.

Either of the both should be used.
Using both #Component and #Named don't make any sense.
Adding to above (Other's) comment #Component("[someComponentID]") and #Named("[someNamedID]") to assign an ID to a bean by passing the ID in the parenthesis, if not implicitly assigned one.

Related

Is #Bean inside of #Component a singleton?

I've read in some places that the difference between #Bean inside of #Component and #configuration, if that the latter provides a singleton bean while the former does not. Can anyone confirm if this is true or not?
When using #Configuration annotated classes those are processed in full mode mode, meaning the class is read using ASM, enhanced with CGLIB so that inter method calls will return the same instance.
Using #Component to declare beans those are process in lite mode. Not allowing for inter method references (you can do it but each call will create a new bean).
See als this section in the Spring Reference Guide which explains this in great(er) detail.
Please specify the meaning of singleton in your question. Actually, in Spring world SINGLETON is the default bean scope and it doesn't matter where bean defined in Component or Configuration its scope will be SINGLETON, but can be overridden by supplying the scope attribute to #Bean annotation. Beans defined in Configuration has some constraints. More details you can find here: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html

How to tell if a class is Spring loaded in java?

I have been given a task to assign a property from .properties file to a non Spring bean class using #Value annotation. To do this, I created a method on a #Component annotated class and set the property into it, then called that method from the non Spring bean class. I thought this would work, however, still showing as null.
I was told this is because the #Component annotated class I used is not spring loaded. Question, how can I tell if a class is Spring loaded bean? I have been searching on google but can't find anything helpful aside from examples with #Component or #Configuration annotations. Thanks.
Spring Container is responsible for creating or managing beans. It all satisfy the dependencies by injecting them either through constructor or setter method. But in your case you want the #Value injection in your non spring bean which is really not possible as per my understanding. Because here the spring does not creating the object then how it satisfy the dependencies of it.
You have two options for this situation.
Either annotate class using #Component
Either read property file using Properties
https://www.mkyong.com/java/java-properties-file-examples/

How to override spring beans with Java config

I encountered this issue when I'm trying to override the RibbonRoutingFilter bean defined in spring zuul. To emphasis, I'm doing an override, not just creating a bean of the same type. So end of the day, I want the "ribbonRoutingFilter" bean from zuul not registered at all.
So I have my own implementation. First thing I tried, I used the #component annotation and autowire the dependencies. Added a breakpoint in the constructor, and it ended up never being called. So I realize my definition must be loaded earlier than zuul's. So I created a configuration class with #Configuration annotation and #Order(Ordered.HIGHEST_PRECEDENCE), and use a #Bean annotation to instantiate my class there. Still, my method is always loaded earlier.
It turned out there's certain order Spring is following when loading configuration classes definitions and that is where overrides happen. Class org.springframework.context.annotation.ConfigurationClassParser has the detailed logic in method doProcessConfigurationClass(). I'll put my simplified summarization or the ordering rule here:
if you application class(where main() method is defined) has any classes defined in it, they are parsed and definition inside them are registered first
then it will registered Beans defined as #component and defined in #Configuration class
then it will add definitions introduced by #Import
then it will add definitions introduced by #ImportResource
then add definitions from #bean methods inside the application class
then from default methods on interfaces( I think it's java 8)
then try to do the same steps above for any parent classes you application class has extended.
This explained why my override was not working. It's because all I have been trying is in step 2. But zuul defined the bean by a #Import which is step 3.
So to solve my problem, I added a #Bean annotated method to my application class there and do the instanciation and the override just happend as expected.
The above summarization might not be accurate, it just give you an idea about what could have failed your override. You'd better debug the ConfigurationClassParser when you are trying your specific use case.

what are #Repository and #Autowired used for. (Spring)

I am learning java for 3 months and sometimes
i can not understand the usage purpose of something.
one topic was dependency injection and spring beans i figured out the finally =)
now i confused with the two annotations #Autowired and #Repository.
First What does Autowiring mean? then
Why should i use them and what is the difference between using them and not using?
Also today i tried to use hibernate in a spring mvc project and i had to search for about 15(cause of class not found errors) jar files beacuse of the dependencies of other jar files used in the project.
is this had to be this way? this makes learning java very hard for the beginners
thanks...
#Repository is an annotation that marks the specific class as a Data Access Object, thus clarifying it's role. Other markers of the same category are #Service and #Controller
#Autowired is an annotation with a completely different meaning: it basically tells the DI container to inject a dependency. More info at http://apollo89.com/java/spring-framework-2.5.3/api/org/springframework/beans/factory/annotation/Autowired.html
Edit
More info at tutorialpoint
or docs.spring.io
Both the annotations have different purposes to be used.
#Autowired: This is same as <bean="xyz" autowire="byType"> you define in the configuration file. The reference variable (dependency) that is annotated with #Autowired, will be injected by Spring container as any matching #Bean found in #Configuration class.
Plus the classes annotated with #Component, #Service, #Repository are too considered as beans so their objects are injected into the matching dependencies.
Spring container scans the beans in the classes you mentioned for "component-scan" or #ComponentScan("xyz").
#Repository: This is also a spring-framework's annotation. When you annotate a class #Repository, spring container understands it's a DAO class and translates all unchecked exceptions (thrown from DAO methods) into Spring DataAccessException.
DAO class is the class where you write methods to perform operations over db.
#Autowired and #Repository are very 2 different concepts.
1.# Repository: This define a class to be a repository, In general term you can use simply #Component but to define specifically, there are 3 more annotations like Controller,service and repository.Mainly 2 advantages:
1.If you have defined(context:component-scan)in servlet.xml to scan the defined package and find its own by spring.
2. More advantages you get from spring like database access error translation, so it is mainly defined to use with class in which you are connecting with database either with hibernate or jdbc.
#Autowired: to inject dependency at run-time by spring, means in a class, autowire a object ,and use it ,so this bean will automatically be made without defining in xml file

Can't I use annotation to indicate a bean is a primary bean

We know in Spring, <bean> has an attribute "primary" to indicate a bean is the first candidate if there are multiple beans are available to be autowired to a property.
But now all my bean definition are declared using #Component/#Service, etc, I can't find the corresponding "primary" attribute I can use to declare a bean.
Please advise how can I achieve this, thanks.
In Spring 3.0, you use #Primary.
Indicates that a bean should be given
preference when multiple candidates
are qualified to autowire a
single-valued dependency. If exactly
one 'primary' bean exists among the
candidates, it will be the autowired
value.
May be used on any class directly or
indirectly annotated with Component or
on methods annotated with Bean.
Using Primary at the class level has
no effect unless component-scanning is
being used. If a Primary-annotated
class is declared via XML, Primary
annotation metadata is ignored, and
<bean primary="true|false"/> is
respected instead.
See ref docs.
The #Primary annotation will only work if you are using Spring 3.0.
In Spring 2.5 there's no equivalent annotation for the primary attribute. You have to use the #Qualifier annotation to specify which bean you want to inject. Another option is to define your own qualifier annotation for the same purpose.
See the docs for more information.

Categories

Resources