Spring autowired using constructor - spring

I want to create a object using few properties, how can I achieve that using Spring #Autowired ?
E.g.-
public class Person{
private String fname;
private String lname;
public Person(String fname, String lname){
this.fname = fname;
this.lname = lname;
}
}
How can I create a object using #Autowired of Person class by passing these properties at runtime.
Atul

Do you really want to autowire the variables? Or do you want to set them explictly when getting the bean?
In the later case, you can simply call ApplicationContext.getBean(Class<T> clz, Object ... arguments), in your case...
Person person = context.getBean(Person.class, "Henry", "Miller");
Obviously that doesn't have anything to do with #Autowired. Or do you want to autowire some strings into it? In that case you normally would use the #Value annotation. Autowired is used to inject beans, which you can do via field injection...
#Autowired
private MyService service;
...via constructor injection...
#Autowired
public Person(MyService service) { ... }
...via setter injection...
#Autowired
public void setMyService(MyService service) {..}
But normally you only autowire beans that way. Strings are no beans, so you have to use #Value...
#Autowired
public Person(#Value('${app.some.property}') final String firstName) {...}
This would inject the configured property of app.some.property into that bean. Of course, this only is good if you actually want to inject something from the application context. If you want to create the Person dynamically, you can use the method above.

Related

#Autowire on field vs #Autowired on Construcor

I am developing a SpringBoot application. Can anyone help me understand what is the difference between the below piece of code. I am working on a restful service and I saw constructor being autowired. I can understand its Constructor Injection. Usually I autowire a field. So I am unable to understand the difference between two.
Scenario 1:
#RestController
public class SomeServiceController {
#Autowired
private ASerice aService;
#Autowired
private BService bService;
}
Scenario 2:
#RestController
public class SomeServiceController {
private ASerice aService;
private BService bService;
#Autowired
public SomeServiceController (AService aService, BService bService)
{
this.aService = aService;
this.bService = bService;
}
}
The difference is that with the constructor injection, the class SomeServiceController can only be created if with this constructor.
So you could even instantiate the class to test it.
With field injection, this is not possible. To instantiate the class for a test, you must use reflection to set the two private services.
It's highly recommended to use constructor expression.
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-collaborators

Spring constructor injection using java config

I have a Class that accepts the following constructor
public Student(int id, String name, Map<String, List<String>> mapInject) {
super();
this.id = id;
this.name = name;
this.mapInject = mapInject;
}
And from spring Java Config, I am injecting the constructor args like below..
#Configuration
public class JavaConfig {
#Bean
public Employee getEmployeeBean() {
Map<String,List<String>> mapInject = new HashMap<String,List<String>>();
//Add map element
return new Employee(3123,"John",mapInject);
}
}
Am i doing constructor injection here? Is this the right way to do so?
I wouldn't use Spring to handle this bean creation, unless you want ALL employees to have the same id and name which I doubt.
The power behind Spring is its Dependency Injection (DI) where you define beans for providers such as database managers, services, etc. and inject those into your components. Defining a #Bean like you have there serves no purpose as now you can only inject employees with an id of 3123 and name John.
It's important to understand that just because you are using Spring it doesn't mean EVERYTHING needs to be handled as a bean - you will always need standard POJOs for housing and passing around state (such as your Employee class) which doesn't need to have anything to do with Spring.
Down the line you might have an EmployeeService for example which houses business logic to fetch employees from a database or something, this could then be configured as a bean so it can be injected across the application.
EDIT
#Configuration
public class JavaConfig {
#Bean
#Autowired //assuming a sessionfactory been is configured elsewhere
public EmployeeService employeeService(final SessionFactory sessionfactory) {
return new EmployeeService(sessionFactory);
}
}
You could then inject this anywhere (maybe in a controller for example):
#RestController
public class EmployeeController {
private final EmployeeService employeeService;
#Autowired
public EmployeeController(final EmployeeService employeeService) {
this.employeeService = employeeService;
}
}
Where the EmployeeController doesn't need to know or care that the userService has a DB connection and doesn't need to worry about configuring it as Spring will handle all of that.

Correct scope for spring beans on Rest Service

I'm creating a REST service using RestEasy and Spring 4.
The service is basically an endpoint for a complex batch process. So clients call the service passing a bunch of parameters and then the processing is triggered.
As there are many parameters that are initially passed to the service, and those parameters are used pretty much everywhere in the system, I've chosen to create a 'helper' bean that will hold the parameters, then every other bean can autowire the 'parameter bean' and use it.
example:
the url called by the client would be: http://localhost/rest/service/execute?processType=A&initialDate=20141220&finalDate=20141231......
The REST Service endpoint would be something like:
#Path("/service")
public class RESTService {
#Autowired
private RequestParams params;
#Autowired
private ProcessOrchestrator orchestrator;
#POST
#Path("/execute")
#Produces(MediaType.TEXT_PLAIN)
public Response executa(
#NotNull #QueryParam("processType") String processType,
#NotNull #QueryParam("initialDate") String initialDate,
#NotNull #QueryParam("finalDate") String finalDate,
...
) {
params.setProcessType(processType);
params.setInitialDate(initialDate);
params.setFinalDate(finalDate);
orchestrator.triggerBatchProcess();
}
}
The RequestParams bean will only hold the parameters values:
#Component
public class RESTService {
private String processType;
private String initialDate;
private String finalDate;
...
// getters and setters
}
And the other beans would #Autowire the params bean and use its parameters:
#Component
public class DataProcessor {
#Autowire
private RequestParams params;
//...
}
#Component
public class DataConverter {
#Autowire
private RequestParams params;
//...
}
#Component
public class FileWritter {
#Autowire
private RequestParams params;
//...
}
The design looks correct, right? Now, my concern is: how do I make sure that a new RequestParams instance is created every time the service is called? Do I need to declare a scope ("request" for instance) for all my beans?

#Autowired in Spring MVC #Controller does not work on a private field

I have a Spring MVC Controller in a very XML-slimmed application, we use a lot of annotations and as little config as possible. The Controller is working and it also has a number of resource values injected. But I've experienced a really strange behavior with this controller; annotated private fields referencing other components will not be injected.
This will not work.
#Controller
public class EntranceUnitController {
#Value("${remote.baseUrl}")
private String baseUrl = "http://localhost";
#Value("${remote.port}")
private String pushPort = "8080";
#Autowired
private HttpClientFactory httpClientFactory;
...
It seems that the httpClientFactory isn't there yet when the private fields are set, if I set a break point to inspect the value there is of course null set when the controller is created.
BUT, if I make a setter for the component and annotate the set-method instead of the private field the controller works as expected.
#Controller
public class EntranceUnitController {
#Value("${remote.baseUrl}")
private String baseUrl = "http://localhost";
#Value("${remote.port}")
private String pushPort = "8080";
private HttpClientFactory httpClientFactory;
#Autowired
public void setHttpClientFactory(HttpClientFactory httpClientFactory) {
this.httpClientFactory = httpClientFactory;
}
...
To me this is really annoying. Isn't the auto wiring injection for annotated values happening at the same time regardless injection point? I.e. why does it matter that the object is injected with a setter? I thought that private field injections are directly followed by constructs and setters, me start to think I'm wrong in that case...
Seems like your dependencies are in fact injected, you are just putting a breakpoint in the wrong moment (too early) and the dependencies aren't injected yet, despite class being already created.
Remember that, unless you are using constructor injection, the first place where you can use injected dependencies is #PostConstruct method:
#Controller
public class EntranceUnitController {
#Autowired
private HttpClientFactory httpClientFactory;
#PostConstruct
public void init() {
httpClientFactory //should not be null
}

Static Fields + Autowiring in Spring

Can we autowire static fields in spring controller ?
eg:
#Autowired
public static JNDIEMailSender jNDIEmailSender;
No, I don't think that will work. You can add a setter method, annotate it with #Autowired and set the static field in the setter.
#Autowired
void setJNDIEmailSender(JNDIEmailSender jndiEmailSender) {
ClassName.jNDIEmailSender = jndiEmailSender
}
Spring doesnt autowire static fields

Resources