Searching beans using component scanning

The following minimum configuration is required to search beans using component scanning in a Spring application:

    package com.packt.patterninspring.chapter4.bankapp.config; 
 
    import org.springframework.context.annotation.ComponentScan; 
    import org.springframework.context.annotation.Configuration; 
 
    @Configuration 
    @ComponentScan 
    public class AppConfig { 
    
    } 

The AppConfig class defines a Spring wiring configuration class same as the Java-based Spring configuration in the previous section. There is one thing to be observed here--the AppConfig file has one more @ComponentScan, as earlier it had only the @Configuration annotation. The configuration file AppConfig is annotated with @ComponentScan to enable component scanning in Spring. The @ComponentScan annotation scans those classes that are annotated with @Component by default in the same package as the configuration class. Since the AppConfig class is in the com.packt.patterninspring.chapter4.bankapp.config package, Spring will scan only this package and its sub packages. But our component application classes are in the com.packt.patterninspring.chapter1.bankapp.service and com.packt.patterninspring.chapter4.bankapp.repository.jdbc packages, and these are not subpackages of com.packt.patterninspring.chapter4.bankapp.config. In this case, Spring allows to override the default package scanning of the @ComponentScan annotation by setting a base package for component scanning. Let's specify a different base package. You only need to specify the package in the value attribute of @ComponentScan, as shown here:

    @Configuration 
    @ComponentScan("com.packt.patterninspring.chapter4.bankapp") 
    public class AppConfig { 
    
    } 

Or you can define the base packages with the basePackages attribute, as follows:

    @Configuration 
    @ComponentScan(basePackages="com.packt.patterninspring.
chapter4.bankapp") public class AppConfig { }

In the @ComponentScan annotation, the basePackages attribute can accept an array of Strings, which means that we can define multiple base packages to scan component classes in the application. In the previous configuration file, Spring will scan all classes of com.packt.patterninspring.chapter4.bankapp package, and all the subpackages underneath this package. As a best practice, always define the specific base packages where the components classes exist. For example, in the following code, I define the base packages for the service and repository components:

    package com.packt.patterninspring.chapter4.bankapp.config; 
    import org.springframework.context.annotation.ComponentScan; 
    import org.springframework.context.annotation.Configuration; 
    @Configuration 
    @ComponentScan(basePackages=       
{"com.packt.patterninspring.chapter4.
bankapp.repository.jdbc","com.packt.patterninspring.
chapter4.bankapp.service"}) public class AppConfig { }

Now Spring scans only com.packt.patterninspring.chapter4.bankapp.repository.jdbc and com.packt.patterninspring.chapter4.bankapp.service packages, and its subpackages if they exist. instead of doing a wide range scanning like in the earlier examples.

Rather than specify the packages as simple String values of the basePackages attribute of @ComponentScan, Spring allows you to specify them via classes or interfaces as follows:

    package com.packt.patterninspring.chapter4.bankapp.config; 
    import org.springframework.context.annotation.ComponentScan; 
    import org.springframework.context.annotation.Configuration; 
    import com.packt.patterninspring.chapter4.bankapp.
repository.AccountRepository; import com.packt.patterninspring.chapter4.
bankapp.service.TransferService; @Configuration @ComponentScan(basePackageClasses=
{TransferService.class,AccountRepository.class}) public class AppConfig { }

As you can see in the preceding code, the basePackages attribute has been replaced with basePackageClasses. Now Spring will identify the component classes in those packages where basePackageClasses will be used as the base package for component scanning.

It should find the TransferServiceImpl, JdbcAccountRepository, and JdbcTransferRepository classes, and automatically create the beans for these classes in the Spring container. Explicitly, there is no need to define the bean methods for these classes to create Spring beans. Let's turn on component scanning via XML configuration, then you can use the <context:component-scan> element from Spring's context namespace. Here is a minimal XML configuration to enable component scanning:

    <?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd"> 
    <context:component-scan base-    
package="com.packt.patterninspring.chapter4.bankapp" /> </beans>

In the preceding XML file, the <context:component-scan> element is same the @ComponentScan annotation in the Java-based configuration for component scanning.