spring应用之装配Bean的方式(六)

第一个问题:对于ComponentScan注解,它只是扫描所在包的java类,但是,更多时候真正需要的是可以扫描所指定的类

@ComponentScan 存在着两个配置项 ,一个是basePackages,另外一个是basePackageClasses。

spring应用之装配Bean的方式(六)

* basePackages可以配置一个java包的数组,Spring会根据它的配置扫描相对应的包和子包,将配置好的Bean,装配起来;

* basePackageClasses可以配置多个类,Spring会根据配置的类所在的包,为包和子包进行扫描装配对应的Bean。

为了验证@ComponentScan的两个配置项,首先定义一个接口IStaffService,

package pro.jamal.blog.demo6;

import pro.jamal.blog.demo5.annotation.Staff;

/**
 * @author: lyj
 * @Date: 2019/6/8
 */
public interface IStaffService {
    public void printStaffInfo(Staff staff);
}

使用接口来编写一些操作类是Spring所推荐的,他可以将定义和实现相分离,这样更为灵活。这里添加一个IStaffService的实现类。

package pro.jamal.blog.demo6;

import org.springframework.stereotype.Component;
import pro.jamal.blog.demo5.annotation.Staff;

/**
 * @author: lyj
 * @Date: 2019/6/8
 */
@Component
public class StaffServiceImpl implements  IStaffService {
    @Override
    public void printStaffInfo(Staff staff) {
        System.out.println("[id="+staff.getId()+"]");
        System.out.println("[name="+staff.getName()+"]");
        System.out.println("[salary="+staff.getSalary()+"]");
    }
}

这里的@Compent表明它Spring所需要的Bean,而且实现了对应IStaffService接口所定义的printStaffInfo方法。

为了装配StaffService和Staff的两个Bean,需要给@ComponentScan加上对应的配置,

package pro.jamal.blog.demo6;

import org.springframework.context.annotation.ComponentScan;
import pro.jamal.blog.demo5.annotation.Staff;
import pro.jamal.blog.demo6.service.impl.StaffServiceImpl;

/**
 * @author: lyj
 * @Date: 2019/6/8
 */
//这里会扫描两个包及其子包
//@ComponentScan(basePackages = {"pro.jamal.blog.demo5.annotation","pro.jamal.blog.demo6"})
//这里会扫描两个类所在的包及其子包
@ComponentScan(basePackageClasses = {Staff.class, StaffServiceImpl.class})
public class ApplicationConfig {
}


* 如果采用多个@ComponentScan去定义对应的包,但每定一个@ComponentScan,Spring就会为所定义的类生成一个新的对象,也就是所配制的Bean将会生成多个实例,这个往往不是我们需要的。

* 对于已定义basePackagesbasePackageClasses的@ComponentScan,Spring会进行专门的区分,也就是说在同一个@ComponentScan中即使重复定义相同的包或者存在其子包定义,也不会造成同一个Bean的多次扫描,而导致一个配置生成多个对象。因此建议不要采用多个@ComponentScan注解进行配置,因为一定有重复的包和子包就会产生重复的对象,这不是我们所需要的。对于basePackages和basePackageClasses的选择问题,basePackage的可读性会更好一些,因此在项目中会优先选择使用它,但是在大量重构的工程中,尽量不要使用basePackages,因为很多时候重构修改包名需要反复地配置,而IDE不会给你任何提示。而采用basePackagesClasses,当你对包移动的时候,IDE会有报错提示,并且可以轻松处理这些错误。

测试

package pro.jamal.blog.demo6;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import pro.jamal.blog.demo5.annotation.Staff;
import pro.jamal.blog.demo6.service.impl.StaffServiceImpl;

/**
 * @author: lyj
 * @Date: 2019/6/8
 */
public class Client {
    public static void main(String[] args) {
        ApplicationContext context =
                new AnnotationConfigApplicationContext(ApplicationConfig.class);
        Staff staff = context.getBean(Staff.class);
        StaffServiceImpl staffService = context.getBean(StaffServiceImpl.class);
        staffService.printStaffInfo(staff);

    }
}
上一篇:多态和向上向下转型


下一篇:sqoop导出数据|Hive|HDFS和脚本编写