By default, the @ComponentScan will recursively scan the package in which the AppConfig class is declared. To change this, you can add a package to the value element (@ComponentScan("com.relentlesscoding.wirebeans.beans")) to scan only that package. If it troubles you that this is not type safe and hinders refactoring (it is a simple string after all), you can also pass Class objects to the basePackageClasses element. It will then scan the package that class is part of. Some people even recommend to create marker interfaces in each package for this purpose, but I think this clutters up the source code too much.

Three ways to declare beans

Now Spring is able to detect our beans. We can declare beans in three ways:

By annotating a class with @Component.

By annotating a method with a non-void return type with @Bean in a class annotated with @Configuration.

By annotating any method with a non-void return type with @Bean.

Automatic configuration with @Component

The simplest way to declare a bean is by annotating a class with @Component:

If we do not specify the value element of @Component, the id of the bean will be the lowercase name of the class, in this case running. We can use this id elsewhere to specify this particular bean, should ambiguities arise.

Explicit configuration in class annotated with @Configuration

If you have control over the beans you are creating, i.e. you are writing the source code, you would always go with automatic configuration by annotating your bean classes with @Component. If you are creating a bean for a class from a library, you can define your beans in your AppConfig class:

Here, we defined a bean of type List<Streak> that we can now inject into any other bean by using the @Autowired annotation (see below).

Lite Beans

Actually, we can declare any method with a non-void return type to be a @Bean. If we declare a bean outside of a configuration class, it will become a “lite bean”. Spring will still manage its lifecycle and scope and we can still autowire the bean into other beans, but when invoking the method directly, it will just be a plain-old Java method invocation without Spring magic. (Normally, Spring would create a proxy around the bean and all invocations would go through the Spring container. This would mean that by default only a single instance of the bean would exist, for example. In “lite” mode, however, the annotated method is just a factory method, and will happily instantiate a new object every time it is called.)

Using the declared beans

To use Spring’s dependency injection, you have a couple of options, all of which involve annotating a method or field with @Autowired. By default, a matching bean of the specified type needs to exist in the Spring context or else Spring will throw an exception. To make the injection optional, set the required element of @Autowired to false.

Constructor injection

For mandatory dependencies, you should use constructor injection. “Mandatory” means the bean would not make sense without the bean on which it depends. For example, a HabitService persists Habits to the database. So a DAO or repository would be a mandatory dependency.

Field injection

Field injection should not be preferred, because it makes testing (e.g. with mocks) harder to pull off. In the following example we inject a dependency into a private field. When we would try to mock the dependency, we would have to deal with the access restriction.

Setter injection

A third way to inject dependencies is through setter injection. Putting @Autowired on any method with one or more parameters will make Spring look for appropriate bean candidates in the Spring context.

We can specify the application context by using the @ContextConfiguration annotation and filling in the classes element. The JUnit 4 annotation @RunWith specifies the SpringRunner.class (which is a convenience extension of the longer SpringJUnit4ClassRunner).