Using @DependsOn to pre initialize dependent beans first to avoid some side effects. These dependent beans are not directly injected in this bean but are still needed to be initialize first to avoid some side effect e.g. in publisher/listener pattern the dependent listeners bean might miss some events publish by this event publisher bean.

@Configuration
@ComponentScan("com.logicbig.example")
public class AppConfig {
@Bean(initMethod = "initialize")
@DependsOn("eventListener")
public EventPublisherBean eventPublisherBean () {
return new EventPublisherBean();
}
@Bean(name = "eventListener", initMethod = "initialize")
// @Lazy
public EventListenerBean eventListenerBean () {
return new EventListenerBean();
}
public static void main (String... strings) {
new AnnotationConfigApplicationContext(AppConfig.class);
}
}
Original PostUsing bean name to avoid ambiguity.

@Configuration
public class AppRunner {
@Bean(name = "OrderServiceA")
public OrderService orderServiceByProvider1() {
return new OrderServiceImpl1();
}
@Bean(name = "OrderServiceB")
public OrderService orderServiceByProvider2() {
return new OrderServiceImpl2();
}
@Bean
public OrderServiceClient createClient() {
return new OrderServiceClient();
}
public static void main(String... strings) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppRunner.class);
OrderServiceClient bean = context.getBean(OrderServiceClient.class);
bean.showPendingOrderDetails();
}
}
Original PostUsing @Scope on a configuration method. This annotation specifies the scope name to be used by the container. Depending on the scope, Spring creates new bean or uses cached bean every time it's accessed by the client. On Spring core framework level, the scope can be singleton or It could be prototype.
Scope valid constants.

@Configuration
public class Config {
@Bean
public UserRegistrationValidator validator () {
return new UserRegistrationValidator();
}
@Bean
public RegistrationService registrationService () {
return new RegistrationServiceImpl();
}
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean
public UserRegistrationBean userRegistrationBean () {
return new UserRegistrationBeanImpl();
}
}
Original PostThis example shows how to use Java based configuration for array injection and ordering the array using @Order annotation.

@Configuration
public class ArrayInjectOrderExample {
@Bean
public TestBean testBean () {
return new TestBean();
}
@Bean
@Order(3)
public String refString () {
return "my string 1";
}
@Bean
@Order(1)
public String refString2 () {
return "my string 2";
}
@Bean
@Order(2)
public String refString3 () {
return "my string 3";
}
public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
ArrayInjectOrderExample.class);
TestBean bean = context.getBean(TestBean.class);
System.out.println(Arrays.toString(bean.getStringArray()));
}
private static class TestBean {
private String[] stringArray;
@Autowired
public void setStringArray (String[] stringArray) {
this.stringArray = stringArray;
}
public String[] getStringArray () {
return stringArray;
}
}
}
Original PostUsing Qualifier to avoid ambiguity.

@Configuration
public class AppRunner2 {
@Bean
@Qualifier("OrderServiceA")
public OrderService orderServiceByProvider1() {
return new OrderServiceImpl1();
}
@Bean(name = "OrderServiceB")
public OrderService orderServiceByProvider2() {
return new OrderServiceImpl2();
}
@Bean
public OrderServiceClient createClient() {
return new OrderServiceClient();
}
public static void main(String... strings) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppRunner2.class);
OrderServiceClient bean = context.getBean(OrderServiceClient.class);
bean.showPendingOrderDetails();
}
}
Original PostThese examples show the different scenarios where a @Configuration class contains @Bean methods with parameters depending on other registered bean instances.

public class BeanB {
private BeanA beanA;
BeanB (BeanA beanA) {
this.beanA = beanA;
}
public BeanA getBeanA () {
return beanA;
}
}
If there's only one type registered for the target injection point parameter then the dependency is resolved by just type.

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class InjectParameterByType {
public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
Config.class);
BeanB beanB = context.getBean(BeanB.class);
System.out.println("In the main method: " + beanB.getBeanA());
}
@Configuration
public static class Config {
@Bean
public BeanA bean1 () {
BeanA beanA = new BeanA();
System.out.println("method bean1: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanB bean2 (BeanA theBean) {
BeanB beanB = new BeanB(theBean);
System.out.println("method bean2: beanB created = " + beanB +
"\n with constructor param BeanA = " + theBean);
return beanB;
}
}
}
Output
method bean1: beanA created = com.logicbig.example.BeanA@22dcf4fa
method bean2: beanB created = com.logicbig.example.BeanB@ad19da9
with constructor param BeanA = com.logicbig.example.BeanA@22dcf4fa
In the main method: com.logicbig.example.BeanA@22dcf4fa
In case if there are more than one bean instances of same type available then we can resolve that with bean's name. In this example the method bean1() registers the BeanA instance with name same as method's name, i.e. 'bean1' which matches the parameter name of bean3(..). Spring always matches the type first before attempting to apply some other additional strategy.

public class InjectParameterByName {
public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
Config.class);
BeanB beanB = context.getBean(BeanB.class);
System.out.println("In the main method: " + beanB.getBeanA());
}
@Configuration
public static class Config {
@Bean
public BeanA bean1 () {
BeanA beanA = new BeanA();
System.out.println("method bean1: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanA bean2 () {
BeanA beanA = new BeanA();
System.out.println("method bean2: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanB bean3 (BeanA bean1) {
BeanB beanB = new BeanB(bean1);
System.out.println("method bean3: beanB created = " + beanB +
"\n with constructor param BeanA: " + bean1);
return beanB;
}
}
}
Output
method bean1: beanA created = com.logicbig.example.BeanA@595532b
method bean2: beanA created = com.logicbig.example.BeanA@1592340b
method bean3: beanB created = com.logicbig.example.BeanB@131f2c23
with constructor param BeanA: com.logicbig.example.BeanA@595532b
In the main method: com.logicbig.example.BeanA@595532b
In this example the dependency is resolve with an explicit use of @Qualifier on both sides.

public class InjectParameterByQualifier {
public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
Config.class);
BeanB beanB = context.getBean(BeanB.class);
System.out.println("In the main method: " + beanB.getBeanA());
}
@Configuration
public static class Config {
@Bean
public BeanA bean1 () {
BeanA beanA = new BeanA();
System.out.println("method bean1: beanA created = " + beanA);
return beanA;
}
@Qualifier("myBean")
@Bean
public BeanA bean2 () {
BeanA beanA = new BeanA();
System.out.println("method bean2: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanB bean3 (@Qualifier("myBean") BeanA theBean) {
BeanB beanB = new BeanB(theBean);
System.out.println("method bean3: beanB created = " + beanB +
"\n with constructor param BeanA = " + theBean);
return beanB;
}
}
}
Output
method bean1: beanA created = com.logicbig.example.BeanA@334b9848
method bean2: beanA created = com.logicbig.example.BeanA@e0c33ff
method bean3: beanB created = com.logicbig.example.BeanB@1a69c4d3
with constructor param BeanA = com.logicbig.example.BeanA@e0c33ff
In the main method: com.logicbig.example.BeanA@e0c33ff
In this example dependency is resolved by matching bean's name of the bean's provider method with target injection point parameter's @Qualifier. Note that opposite is not possible, i.e. we cannot match a @Qualifier of provider's method with target injection point parameter's name.

public class InjectParameterByQualifier2 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
Config.class);
BeanB beanB = context.getBean(BeanB.class);
System.out.println("In the main method: " + beanB.getBeanA());
}
@Configuration
public static class Config {
@Bean
public BeanA bean1 () {
BeanA beanA = new BeanA();
System.out.println("method bean1: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanA bean2 () {
BeanA beanA = new BeanA();
System.out.println("method bean2: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanB bean3 (@Qualifier("bean2") BeanA theBean) {
BeanB beanB = new BeanB(theBean);
System.out.println("method bean3: beanB created = " + beanB +
"\n with constructor param BeanA = " + theBean);
return beanB;
}
}
}
Output
method bean1: beanA created = com.logicbig.example.BeanA@7df9cdea
method bean2: beanA created = com.logicbig.example.BeanA@729f4474
method bean3: beanB created = com.logicbig.example.BeanB@2bb1c183
with constructor param BeanA = com.logicbig.example.BeanA@729f4474
In the main method: com.logicbig.example.BeanA@729f4474
This example demonstrates multiple @Qualifier matches on both sides.

public class InjectParameterByQualifier3 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(
Config.class);
BeanB beanB = context.getBean(BeanB.class);
System.out.println("In the main method: " + beanB.getBeanA());
}
@Configuration
public static class Config {
@Bean
public BeanA bean1 () {
BeanA beanA = new BeanA();
System.out.println("method bean1: beanA created = " + beanA);
return beanA;
}
@Bean
@Qualifier("myBean")
public BeanA bean2 () {
BeanA beanA = new BeanA();
System.out.println("method bean2: beanA created = " + beanA);
return beanA;
}
@Bean
public BeanC bean3 () {
BeanC beanC = new BeanC();
System.out.println("method bean3: beanC created = " + beanC);
return beanC;
}
@Bean
@Qualifier("myBean2")
public BeanC bean4 () {
BeanC beanC = new BeanC();
System.out.println("method bean4: beanC created = " + beanC);
return beanC;
}
@Bean
public BeanB bean5 (@Qualifier("myBean") BeanA theBean,
@Qualifier("myBean2") BeanC theBean2) {
BeanB beanB = new BeanB(theBean);
System.out.println("method bean5: beanB created = " + beanB +
"\n with constructor param of type BeanA= " + theBean);
System.out.println("method bean5: theBean2 instance (can also be in as constructor " +
"arg or some " +
"other way): " + theBean2);
return beanB;
}
}
}
Output
method bean4: beanC created = com.logicbig.example.BeanC@440a5936
method bean3: beanC created = com.logicbig.example.BeanC@6bce6f30
method bean1: beanA created = com.logicbig.example.BeanA@32208ffa
method bean2: beanA created = com.logicbig.example.BeanA@fd85dc7
method bean5: beanB created = com.logicbig.example.BeanB@8558531
with constructor param of type BeanA= com.logicbig.example.BeanA@fd85dc7
method bean5: theBean2 instance (can also be in as constructor arg or some other way): com.logicbig.example.BeanC@440a5936
In the main method: com.logicbig.example.BeanA@fd85dc7
Original PostThis example shows, how to use @Conditional
to selectively include/exclude beans from registration.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
@Conditional(LocaleConditionUSA.class)
public MyService myBeanA () {
return new MyServiceA();
}
@Bean
@Conditional(LocaleConditionCanada.class)
public MyService myBeanB () {
return new MyServiceB();
}
@Bean
public ClientBean clientBean () {
return new ClientBean();
}
}
Original PostUsing autowiring mode Autowire.BY_NAME
. We need to use @Autowired at the injection point. ServiceBean serviceBean1()

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class AutowireByName {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
@Bean
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
@Autowired
private ServiceBean serviceBean1;
public void doSomething () {
System.out.println(serviceBean1.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Output
Service bean 1
Original PostUsing @Bean element with autowire=Autowire.BY_NAME.

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* In this example we are explicitly giving the bean a name by using @Bean(name =....)
*/
public class AutowireByName2 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean(name = "someOtherServiceBean")
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
@Bean
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean someOtherServiceBean;
@Autowired
public void setSomeOtherServiceBean (ServiceBean serviceBean) {
this.someOtherServiceBean = serviceBean;
}
public void doSomething () {
System.out.println(someOtherServiceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Output
Service bean 1
Original PostUsing @Bean element with autowire=Autowire.BY_NAME.

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* In this example we are explicitly giving the bean a name by using @Bean(name =....)
*/
public class AutowireByName3 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
@Bean(name = "myService")
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean serviceBean;
@Autowired
@Qualifier("myService")
public void setServiceBean(ServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
public void doSomething () {
System.out.println(serviceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Output
Service bean 2
Original PostUsing @Bean element with autowire=Autowire.BY_NAME.

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* In this example we are explicitly giving the bean a name by using @Bean(name =....)
*/
public class AutowireByName4 {
public static void main (String[] args) {
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(Config.class);
ClientBean bean = context.getBean(ClientBean.class);
bean.doSomething();
}
@Configuration
public static class Config {
@Bean(autowire = Autowire.BY_NAME)
public ClientBean clientBean () {
return new ClientBean();
}
@Bean
public ServiceBean serviceBean1 () {
return new ServiceBean("Service bean 1");
}
@Bean
@Qualifier("myService")
public ServiceBean serviceBean2 () {
return new ServiceBean("Service bean 2");
}
}
private static class ClientBean {
private ServiceBean serviceBean;
@Autowired
@Qualifier("myService")
public void setServiceBean(ServiceBean serviceBean) {
this.serviceBean = serviceBean;
}
public void doSomething () {
System.out.println(serviceBean.getMsg());
}
}
private static class ServiceBean {
private String msg;
public ServiceBean (String msg) {
this.msg = msg;
}
public String getMsg () {
return msg;
}
}
}
Output
Service bean 2
Original PostConstructor based DI with @Autowired and @Qualifier.

@Configuration
@ComponentScan({"com.logicbig.example.scan"})
public class ConstBasedDIWithScan {
@Bean
public OrderService orderService() {
return new OrderService();
}
public static void main(String... strings) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
ConstBasedDIWithScan.class);
OrderServiceClient bean = context.getBean(OrderServiceClient.class);
bean.showPendingOrderDetails();
}
@Component
public static class OrderServiceClient {
private OrderService orderService;
@Autowired
OrderServiceClient(OrderService orderService) {
this.orderService = orderService;
}
public void showPendingOrderDetails() {
System.out.println(orderService.getOrderDetails("500"));
}
}
}
Original Post