Spring : Autowire - spring

If I initialize one object manually ,inside that class I have autowired some of the other classes , Does spring creates and instances of Autowired objects ?
Example :
Class A {
#Autowired
B b;
}
Class main {
main(){
A a = new A();
//Does spring initialize B class also automatically(Autowired)?
}
}

No, Class A by itself has to be managed by spring as well as class B
In general Autowiring works only for classes that are managed by spring

Related

Spring custom annotation for bean injection

I am looking to inject a bean by means of a custom annotation
#Service
class Foo(#MyBean val bar: Bar) { fun someMethod() { bar.invoke() } }
with
#Retention(AnnotationRetention.RUNTIME)
#Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
annotation class MyBean
Currently we have a configuration class that defines multiple bean methods
#Configuration
class config {
#Bean
fun bar(): Bar = { getBaz() }
}
I have seen implementations of BeanPostProcessor but that seems to add behaviour to already existing beans. My question is, is there a way to initialise and assign beans to a field by means of a custom annotation.
Since you're injecting the field through a constructor, you don't need to annotate the field itself, but rather the constructor.

Spring Boot - Order of Bean creation

Is there any default bean initialization order implicitly in a Spring Boot application? I came across this question in one of my Spring Boot applications when trying to use #ConditionalOnBean annotation.
At first, I thought that Spring does not guarantee any Bean creation order when it's loading beans in #Configuration class or when it's doing component-scan to auto register #Component/#Service/.. classes.
But later, I noticed that in the Spring documentation, it mentions that,
Auto-configuration classes are guaranteed to load after any user-defined bean definitions have been added.
This somehow makes me confused,
1. What counts user defined bean and what counts auto-configuration classes? Specifically, is there any loading order between #Bean in #Configuration class and #Component/#Service directly on class level.
2. If a bean A needs dependency injection of bean B, will B always be initialized first?
3. If #Import is used for configuration aggregation in a Spring Boot application, will beans defined in the imported configuration class being initialized before component-scanned bean registration.
#Component
public class A {}
#Component
public class B {
#Autowired
private A a;
}
#Configuration
public class externalConfig {
#Bean
public C c() {
return new C();
}
}
#SpringBootApplication
#Import(externalConfig.class)
public class testApplication {
#Bean
public D d() {
return new D();
}
}
When comes to the above code example, my question becomes the following.
1. Without #Import, will C or D always be initialized before A and B?
2. Will B always be initialized before A?
3. With #Import, will C always be initialized first, like even before D?
Not 100% sure, but:
No there is no guarantee.
A will be initialized, then B, cause you're injecting A.
Import is not guaranteeing the order, only if you have some not lazy injections
Check the DependsOn annotation (enter link description here).
I hope it helps you,

Spring Boot configuration for non-beans [duplicate]

This question already has answers here:
Injecting beans into a class outside the Spring managed context
(8 answers)
Closed 3 years ago.
Introduction
I have some business logic properties in the application.yml file.
They are loaded into the application via a #ConfigurationProperties annotated class.
How could I use these properties in a class which is not a Spring Bean? It cannot be a singleton, because many objects of it must be created during run-time.
Example
application.yml
business.foo: 2
BusinessProperties.java
#ConfigurationProperties("business")
#Getter // lombok
#Setter // lombok
public class BusinessProperties {
private int foo;
}
TypicalBean.java
#Component
public class TypicalBean {
private final BusinessProperties properties;
#Autowired
public TypicalBean(BusinessProperties properties) {
this.properties = properties;
}
#PostConstruct
public void printFoo() {
System.out.println("Foo: " + properties.getFoo()); // "Foo: 2"
}
}
NonBean.java
public class NonBean {
public void printFoo() {
System.out.println("Foo: ???"); // How to access the property?
}
}
Is there some way to create a non-singleton class, which can have access to configuration (or even other Spring beans) but otherwise works the same as a regular java class? Meaning that I can control its creation, it is collected by the garbage collector if not used anymore, etc.
You can still define the NonBean.class as a Component with Scope.Prototype
#Component
#Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
public class NonBean {
#Autowired
public TypicalBean(BusinessProperties properties) {
this.properties = properties;
}
public void printFoo() {
System.out.println("Foo: " + properties.getFoo());
}
}
The trick is how you create an instance of NonBean.class. In the code where you'll be creating an instance of NonBean.class, use Spring's ObjectFactory<T>
private final ObjectFactory<NonBean> nonBeanFactory;
...
NonBean nonBean = nonBeanFactory.getObject();
The instantiated nonBean object will have been autowired.
All spring-beans creates by SpringApplicationContext. Bean - it's simple POJO-object, but created by Spring and saved in his container. If you want to get access to bean from outside of container - see this:
Getting Spring Application Context
Spring beans are really meant to be used within the application context but you might be able to achieve what you want by autowiring the properties to a static field in a Spring bean.
#Component
public class BusinessPropertiesUtils {
public static BusinessProperties INSTANCE;
#Autowired
public setBusinessProperties(BusinessProperties properties) {
this.INSTANCE = properties;
}
}
And then:
public class NonBean {
public void printFoo() {
System.out.println("Foo: " + BusinessPropertiesUtils.INSTANCE.getFoo());
}
}
PS: this is very hacky and definitely not the "Spring way".
You can configure beans with the prototype scope, which will give you a new instance of the bean every time it's requested.
From the Spring documentation:
In contrast to the other scopes, Spring does not manage the complete lifecycle of a prototype bean. The container instantiates, configures, and otherwise assembles a prototype object and hands it to the client, with no further record of that prototype instance.
...
In some respects, the Spring container’s role in regard to a prototype-scoped bean is a replacement for the Java new operator. All lifecycle management past that point must be handled by the client.
Example of how you can convert the TypicalBean class to a prototype scoped bean:
#Component
#Scope("prototype")
public class TypicalBean {
...
}
Another alternative is to manually instantiate the bean class (or any POJO) and injecting the dependencies (configuration, spring beans, etc.) through the constructor or setter methods, if you have them available or can get them from the Spring Context.
new TypicalBean(properties);

Not able to inject values in a field

#Component
#PropertySources({ #PropertySource("classpath:mail.properties") })
public class A implements B {
#Value("${mail.team.address}")
private String teamAddress;
// has getter and setters .not shown for brevity.
Now when i call the class i get the value of teamAddress as NULL .But in the property file mail.team.address has some value.
My property file is present under src/main/resource folder
Making a call
A a = new A ();
a.someMethodinClassA();
You can not create instance of class by yourself when you want Spring to resolve #Value annotation.
See documentation:
Note that actual processing of the #Value annotation is performed by a BeanPostProcessor which in turn means that you cannot use #Value within BeanPostProcessor or BeanFactoryPostProcessor types. Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation).
Simple solution for you: just annotate class with any #Component annotation and let Spring to create an instance of your class.
You can't create (with a "new" keywoard) for spring bean. If you do it like this, spring doesn't participate in the object creation and configuration, which means that there is no autowiring, the bean is not in Application Context, etc. And of course, #Value annotation won't be processed among other things
The better way is to inject the class A to the code that you used in your example:
A a = new A ();
a.someMethodinClassA();
Show become:
#Component
public class SomeClass {
private final A a;
public SomeClass(A a) {
this.a = a;
}
public void foo() {
a.someMethodinClassA();
}
}
You should read some basics around spring dependency injection. The class that you have autowired with #Component is scanned via component scanning and its object is created by spring container for you.
that is the reason you should not create the object yourself using new keyword.
wherever in your new class you want to use your class A object you can autowire it as below:
#Component
public class TestC{
private A a; // this object will be injected by spring for you
}

Dependency Injection with Grails Spring DSL

When I use the Spring DSL provided by Grails is it possible to do constructor injection. If so, an example would be much appreciated.
If constructor injection is not possible, is there some other way that I can inject a spring bean without making the dependencies public properties. Using Spring in a Java project I can do this
class Foo {
#Autowired
private Bar bar
}
And it will autowire the Bar dependency either by name or type
it is possible to use constructor injection even using the BeanBuilder DSL
bb.beans {
exampleBean(MyExampleBean, "firstArgument", 2) {
someProperty = [1,2,3]
}
}
whenever you want to reference other beans as constructor arguments, use the ref() method
bb.beans {
exampleBean(MyExampleBean, "firstArgument", ref('anotherBean')) {
someProperty = [1,2,3]
}
}
You should be able to inject a bean into the constructor using the #Autowired annotation like you'd usually do in Spring. Here's an example:
class Foo {
private final Bar bar
#Autowired
public Foo(Bar bar) {
this.bar = bar
}
}

Resources