I have two classes says A and B, B is annotated with #Repository annotation and A class has a reference variable of B type annotated with #Resource type.I know the meaning of both annotations.
I am not using xml configuration. Do I need to put the tag
<context-component-scan base-package = ""/>
to point out above classes or Spring will automatically scan the all class path.
I know this is a simple question but I am in confusions because
spring doc says, auto scan of class path
I have a large project and not able to find the entry for for a particular case as given above (A and B class case)
Thanks
Spring doesn't do component scanning if you don't tell it to.
You'll need to provide a <component-scan> element to scan for #Component (or the sub annotations) annotated types and have Spring generate corresponding bean definitions. Try to restrict the base-package so as not to get any unexpected results.
Related
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/
I am trying to understand how beans that we make using #Configuration tends to override the beans that are generated by SpringBoot by default. I have been working on a project where in many cases we create beans for things like ZuulConfigs and the assumption is, whatever we are making shall take precedence over the default generated bean. I have been trying to figure this out but can't. Basically,
Is Spring achieving this via some custom class loader
If not how is this precedence working. Can I give some precedence in similar manner to my beans
Can I generate similar hierarchy in my project,if so how
The help is highly appreciated
Spring AutoConfiguration is used to provide a basic configuration if certain classes are in the classpath or not.
If you want to configure the order in which beans are instantiated by spring you can use
#DependsOn("A")
public class B {
...
}
This would create bean "A", then "B". Hence you can order the configuration depending upon the beans need first to be done. Anyways Spring automatically detects the dependencies by analyzing the bean classes.
for more help check this question
Spring Boot AutoConfiguration Order
Alternative :
There is also "#AutoConfigureOrder" annotation(where you can prioritise the configuration), you can have a look in the code for deeper understanding.
Documentation of AutoConfiguration is here
First of all, class loading and bean creation are two different things. We don't need to create a bean to load a class, however, a class has to be loaded in order to create a bean.
Now, coming back to Spring's example, Spring looks into all the packages configured by #componentScan and creates beans of all the classes annotated with #Bean, #Configuration and/or #Component. Spring's container keeps track of all the beans created and hence, when it encounters user defined bean with same name and class type as default bean, it replaces the original definition with user defined one (e.g. we can create our custom #ObjectMapper to override Spring boot's own instance). You can also use #Primary annotation to make you bean take precedence if another definition with same class exists (documentation here).
Below are the answers for your questions:
Spring uses reflection to load the classes and create instances. Although you can load the classes with your custom class loader (more on that here), you don't need to worry about it for #Configuration.
Yes, you can use #Primary annotation to give your bean a precedence. You can also use #Order(here) to define the creation order for your beans.
With #Primary, #Order and #Qualifier annotation you can define your own hierarchy for bean creation.
Can I give some precedence in similar manner to my beans
Yes.
A) To define a specific order your Configuration classes will be handled (by the way, a Configuration class does not have to be annotated with #Configuration (so-called full definition), but it's enough to be annotated with #Component, #ComponentScan, #Import, #ImportResource or just have a method annotated with #Bean - so-called lite definition), you should
1) add your Configuration Candidates to your SpringApplication's primarySource, for example, in your main method like that
SpringApplication.run(
new Class[]{YourSpringBootApplication.class, Config1.class, Config2.class, ...},
args);
2) and annotate each of your Configuration Candidates with #Order annotation, any other ordering means like Ordered interface, #DependsOn etc will be ignored by ConfigurationClassPostProcessor, the order in the primarySource array will also be ignored.
Then ConfigurationClassPostProcessor will sort your Configuration Candidates and handle them according the #Order annotation value you specified.
B) The precedence can also be achieved by defining your own AutoConfiguration classes. Although both Configuration and AutoConfiguration are handled by the same ConfigurationClassPostProcessor, they are essentially distinctive machineries. To do so
1) define in your classpath /META-INF/spring.factories file and put in the EnableAutoConfiguration section of it your AutoConfiguration classes like that
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
your.package.AutoConfig1,your.package.AutoConfig2
2) and annotate your AutoConfiguration classes with #AutoConfigureOrder, #AutoConfigureAfter, or #AutoConfigureAfter annotations, any other ordering means again will be ignored.
Like #Strelok pointed out, AutoConfiguration classes, your own and provided e.g. by spring-boot-autoconfigure library alike, will be added to the end of the list of Configuration Candidates.
Remember, however, that the order the Configuration Candidates will be handled by ConfigurationClassPostProcessor does not necessarily coincide with the order the beans defined by the Configuration classes will be created. For example, you might define your Configuration class that overrides TomcatServletWebServerFactory to make your own customization of Tomcat web server like
#Configuration
public class EmbeddedTomcatConfig {
#Bean
public TomcatServletWebServerFactory containerFactory() {
...
return customizedTomcatWebServerFactory;
}
but this method will be called right at the moment when your Spring Boot application decides to create a Web server, regardless of how you defined the precedence for your EmbeddedTomcatConfig Configuration class.
Is Spring achieving this via some custom class loader
There is no need to. Although you could, as always with Spring, define your own ClassLoader for BeanFactory, standard ClassLoader is good enough if everything you need for Configuration in your application is available in the classpath. Please notice, that at first phase ConfigurationClassPostProcessor does not load (i.e. does not resolve) the Configuration candidates classes (otherwise, most of the classes in spring-boot-autoconfigure library will fail to load). Instead it analyzes their annotations with bytecode analyzer, ASM by default. For that purpose, it is just enough to get a binary form, a byte array, of a class to feed it to bytecode analyzer.
Just know this: Spring Boot (specifically) auto configuration classes are always configured last. After all user beans have been created. Spring Boot auto configuration classes almost always use the #ConditionalXXXX annotations to make sure that any beans of the same type/name and other conditions that are configured in your application will take precedence over the Spring Boot auto-configured beans.
If you want your #Component to take precedence over other #Component while scanning all the components by spring, use #Order(Ordered.LOWEST_PRECEDENCE) i.e. the max value to load your component over other.
#Primary is used to give your bean a default preference, we can override the default preference using #Qualifier
I'm trying to get a better understanding of the #Autowired annotations component scanning, but all the examples I found so far use context.getBean(..) at some point to get at least one Bean to start with.
I also read that doing that is considered bad practice , but I can't seem to find any information on how to do it without context.getBean(..)
Could somebody please enlighten me with an example and information on how to do this ?
Define your bean in xml and use
<context:component-scan base-package="com" />
<mvc:annotation-driven />
Bean def
<bean id="processEngine" class="com.processEngine">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
now you can get bean as following
#Autowired
private ProcessEngine processEngine;
how it works
spring scans the bean's recipes either from xml or java configuration. then spring creates a beanDefinitions which are 'loaded' into BeanFactory. BeanFactory triggers a set of BeanPostProcessors (BPP) which are scanning classes for particular annotations like Autowired/Resource/PostProcessor and etc. and do appropriate actions. in case when your class contains #Autowired annotation, AutowiredAnnotationBeanPostProcessor would auto wire required field (dependencies), and when creation of an object is done and all BPP worked out, object is ready to be used by the app, from this point your code can get 'ready' objects from container.
there are some cases when you would need to access this beans from the code which is out of spring's control and not managed by container. in order to do so, you would need to get the ApplicationContext (container) and call #getBean specifying either name or type. using applicationContext directly is not a good practice because there are some problems that you can come to, f.ex. id of a bean might be changed and if you refer to bean by id then NPE would be thrown.
configuration
there are several approaches to configure spring to scan the classes for finding bean recipes. one would be defining component-scan, in this case classes which are located in the path that you've set and having any of valid spring annotations like #Component, #Service, #Repository, #Controller (for web container) would be considered. another way would be specifying each bean separately using <bean> or #Bean.
examples.
if you want to create a web app then you should see DispatcherServlet with ContextLoaderListener classes. this classes would boot your app and load everything according to configuration. f.ex. here,
but if you want to create a desktop app, then you would end up with something like this
From time to time (usually when not using Spring Boot), I use something along the lines of the following code:
public static <T> T autowire(ApplicationContext ctx, T bean) {
ctx.getAutowireCapableBeanFactory().autowireBean(bean);
return bean;
}
In my main, I create an instance of the main application class that contains a few #Autowired annotations for the main services / entry points to my Spring application.
I am using Spring AOP with aspectj-autoproxy.
I use the #Around annotation to intercept certain classes and methods.
#Around(value = "#annotation(counter)")
This code should intercept methods annotated with #Counter annotation.
My question is, does this definition forces scan of all classes in the class path?
I am asking because I have a huge project that can suffer several minutes of loading time if all the class path will be scanned.
And if the answer is yes, how can I disable he scanning?
Limit the scan using:
execution(* com.my.package..*.*(..)) && #annotation(counter)
It will only scan the defined Spring beans, thus not the complete class path.. In addition the annotation #Counter should be specified as the Fully-Qualified Class Name and I don't think "counter" is the correct one..
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