Spring #Autowire instance variable without xml config - spring

I am trying to autowire java.util.concurrent.ConcurrentHashMap to enforce a singleton implementation without using any spring-config.xml file. I'm fairly certain there is a way to do this via some spring annotation directly at the Java side of things, is this possible?
#Component
public class MyClass{
//Some annotation goes here?
private ConcurrentHashMap<String, String> myMap;
}

Actualy, you can not inject MAP.
But you can wrap your map in another class then inject it.
#Component
Public class MapWrapper {
public Map<String, String> map = newConcurrentHashMap<String, String>();
}
...
#Inject
private MapWrapper wrapper;
...

Related

Does spring inject any beans provided in the #Configuration class

If I have a #Configuration class where I have a bean like below, will the dataMap be resolved in the constructor of the DataService class. What type of dependency injection is this? Is it by type because the name for sure doesn't match?
#Bean
public Map<String, List<Data>> data() {
final Map<String, List<Data>> dataMap = new HashMap<>();
readings.put("1", new Data());
return dataMap;
}
and a class
#Service
public class DataService {
private final Map<String, List<Data>> information;
public DataService(Map<String, List<Data>> information) {
this.information = information;
}
}
#Configuration annotation serves as a placeholder to mention that whichever classes annotated with #Configuration are holding the bean definitions!
When Spring application comes up, spring framework will read these definitions and create beans (or simply objects) in IOC (Inversion of control) container These would be Spring managed objects/beans !
To answer your question, it should create a bean and this is a setter based injection!
However, your #Bean must be some user defined or business entity class in ideal scenarios!
Few links for you to refer to:
https://www.codingame.com/playgrounds/2096/playing-around-with-spring-bean-configuration
https://www.linkedin.com/pulse/different-types-dependency-injection-spring-kashif-masood/

Is it bad to put #Service/#Component along with #Bean?

Suppose I have this service bean:
#Service
public class MyService{
private final HashMap<String,String> values;
...
}
with the values being:
com.foo:
values:
a: world
b: helo
I may want to create it inside of a configuration:
#Configuration
#ConfigurationProperties(prefix="com.foo")
public class MyConf{
private Map<String, String> values;
#Bean
public MyService myService(){
return new MyService(values);
}
}
But I fear that spring could do something strange like creating 2 beans or dunno what...is this a good practice or should I just move #ConfigurationProperties inside of the #Service itself?
You can inject your configuration directly into your Service
#Service
public class MyService{
private final MyConf conf;
public MyService(MyConf conf) {
this.conf = conf;
}
}
And remove the #Bean annotation from MyConf allong with myservice method.
You should not do that, as it will create two beans of the same type.
In your case, you have not mentioned different names for the beans
so it will override if spring.main.allow-bean-definition-overriding=true else it will fail.
PS: For #Service annotation to create a bean, the class package should be configured in the #ComponentScan or in the base scan package
If you want to use your properties values in your Service class (or anywhere else) you should just inject it :
#Service
public class MyService{
#Autowired
private MyConf myConf;
}

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.

Autowiring into JPA converters

I am using a customized ObjectMapper in my spring boot app. I also use the JPA converters for several fields which are stored as JSON strings in the DB. I am not sure how to autowire my custom object mapper into my converter.
#Convert(converter=AddressConverter.class)
private Address address;
And my AddressConverter is
class AddressConverter implements AttributeConverter<Address, String> {
#Autowire
ObjectMapper objectMapper; //How to do this?
.....
.....
}
How to autowire ObjectMapper into AddressConverter? Is there a way to do this with Spring AOP?
Maybe you can do it by changing it to a static property, like this:
#Component
class AddressConverter implements AttributeConverter<Address, String> {
private static ObjectMapper objectMapper;
#Autowired
public void setObjectMapper(ObjectMapper objectMapper){
AddressConverter.objectMapper = objectMapper;
}
.....
.....
}

How to initialize List inside Object using Spring Annotation

How do I initialize List inside Object using Spring Annotation
#Component
class Accounts{
private List<Transaction> _transaction;
//getter setter
}
How do I initialize List<Transaction> _transaction; using Spring Annotation or else i
have to define it in xml file.
But i dont want to write any xml file
You can use the Spring Java #Configuration for such a task:
#Configuration
public class SpringConfig {
#Bean
public List<Transaction> transactions() {
...... //Your logic to generate the list..
return transactions;
}
}
And in your Accounts class you have to use #Resource, not #Autowired, the semantics of injecting a list is a little different - if you use #Autowired, any bean of the same type will get injected into the list.
#Component
class Accounts{
#Resource(name="transactions")
private List<Transaction> _transaction;
//getter setter
}
This is pure java solution and there is no xml involved in creating the list..
If Transaction is a Bean with #Service, #Component or #Repository Annotation, you can just write #Autowired on top of your field.
#Component
class Accounts{
#Autowired
private List<Transaction> _transaction;
//getter setter
}

Resources