Reputation: 5628
I have an EmployeeService Spring Service class that I go around injecting everywhere in my application, e.g.
public class ClassX {
@Bean
EmployeeService employeeService;
}
public class ClassW {
@Bean
EmployeeService employeeService;
}
This is how EmployeeService bean looks like (Not sure if it is important for the answer)
public class EmployeeService {
@Bean
SalaryService salaryService;
@Bean
IdentificationService identificationService;
}
If I am not wrong, through out the application context the EmployeeService bean will be the same i.e. a Singleton (Unless defined otherwise)
But there is one place where I would like to use the EmployeeService bean that would not be shared by any other class. Let's say for e.g.
public class ClassY {
@Bean
EmployeeService employeeService;
}
Only in ClassY I want the bean to be a new one, not the one used by the rest of the application.
I am new to Spring so don't know how to exactly define what I am searching for as I am not completely familiar with the language and terms of the framework.
Please feel free to let me know if the question is not clear and any more information is needed.
P.S. I am using XML configuration for Spring and for the rest of the application i.e. apart from ClassY I would like the EmployeeService bean to be a Singleton only
Upvotes: 0
Views: 4299
Reputation: 8641
You can define two different @Beans
and distinguish it with using @Qualifier
.
In Java config:
@Bean //This bean is singleton by default
@Qualifier("employeeServiceA")
public EmployeeService employeeServiceA() {
new EmployeeService();
}
@Bean
@Qualifier("employeeServiceB")
@Scope("prototype")
public EmployeeService employeeServiceB() {
new EmployeeService();
}
When @Autowired
just the @Qualifier
value that you need
@Autowired
@Qualifier("employeeServiceB")
private EmployeeService employeeService;
For XML configuration just define the id
of the bean and then use this id as a @Qualifier
value.
<bean id="employeeServiceA" class="com.package.to.EmployeeService">
<bean id="employeeServiceB" scope="prototype" class="com.package.to.EmployeeService">
There is also @Primary
. Annotate the singleton bean with this annotation and you won't need to use @Qualifier
to indicate that you need this bean to be injected.
The same with XML config:
<bean id="employeeServiceA" primary="true" class="com.package.to.EmployeeService">
P.S. Do not use field injection. It's considered a bad practice. Use constructor injection instead.
Upvotes: 2
Reputation: 181
simple.. above the bean you want to be prototype add @Scope("prototype"):
public class ClassY {
@Scope("prototype")
@Bean
EmployeeService employeeService;
}
that instance will have a different scope
Upvotes: 0
Reputation: 8495
Only in ClassY I want the bean to be a new one, not the one used by the rest of the application.
As this instance will be used at only one class, Use the classic 'new' operator, Spring is NOT restricting you to do this, whenever necessary.
EmployeeService employeeService = new EmployeeService();
Use @Autowired instead of @Bean to inject dependencies.
public class ClassX {
@Autowired
EmployeeService employeeService;
}
Upvotes: 0
Reputation: 3673
I am not able to understand why only in one class you want it not to be shared. There is something fishy in your Bean class, if the requirement is like that. If EmployeeService is thread-safe, it should be ok to be shared.
So its design issue, if you want to achieve this.
But still Spring will support your requirements, define 2 beans of same class with diff names and use them by qualifier.
Upvotes: 0
Reputation: 1131
Use name attribute with the Bean annotation. Thus you can have two beans created for the same class. One will be singleton and the other one which is also singleton can be used exclusively with your class ClassY.
@Bean(name="secondBean")
Hope this will solve your problem.
Upvotes: 0