Spring 配置类

Spring 配置类

介绍

Spring 提倡使用注解和配置类来完成 Bean 的装配,而配置类就是全面取代 xml配置文件 的一种方式
推荐使用扫描和配置类开发项目

导入(装配) Bean 的三种方:

  1. @ComponentScan(扫描)
  2. @Import(导入/整合)
  3. @Bean(配置类中装配)

类注解

@Configuration

用于标识一个类为合法的 Spring配置类
不加 @Configuration 就是 Lite,加 @Configuration 就是 Full

Lite[非代理](简单、迷你):性能最高,不使用代理
Full[代理](全面):使用代理

只有加了 @Configuration 才享有完整的容器功能,否则只有 @Bean 功能

Full底层(猜测):对配置类进行动态代理,对所有方法增强(判断是否有@Bean注解,选择执行)

代理的作用:使用者不直接于被使用者联系,而是通过代理去联系,同时代理可以进行一些额外的操作(比如:返回存储的对象而不执行new对象)

@ComponentScan(扫描)

用于扫描指定的包,装配相关的Bean,对应xml中的扫描

@Import(导入/整合)

  1. 导入普通的 Bean(不推荐)
    比如:@Import({UserController.class, UserServiceImpl.class})

  2. 导入其他配置类(推荐)
    在项目中模块化配置类,包括 mvc 的配置类、mybatis 配置类、Redis 配置类、RabbitMQ 配置类等等
    那么可以在一个总配置类中导入其他这些配置类进行合并,
    这样维护性扩展性更强
    比如:@Import({MvcConfig.class,MybatisConfig.class})

  3. 选择性导入(推荐)
    即按照指定的逻辑来导入相关的类
    这种方式需要自定义一个或者多个导入选择器交给 spring 执行,
    而导入选择器的目的是找到并返回完整类名的集合(不管使用什么手段)
    比如:@Import(AnnoImportSelector.class)

    public class AnnoImportSelector implements ImportSelector {
    /**
     * 自定义导入逻辑
     * @param importingClassMetadata
     * @return 返回值就是所有需要导入的类的完整类名
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 需要导入的类的完整类名的集合
        List<String> classNameList = new ArrayList<>();
        /* 扫描(不管使用什么方法,只要能把完整类名放到集合就可以) */
        return StringUtils.toStringArray(classNameList);
    }
    }

@PropertySource

将 properties 文件的属性注入到配置类的字段中,使用 @Value 注入
比如

@PropertySource("jdbc.properties")
class 类{}

方法注解

@Bean

用于标识 Bean,而其中方法名代表 Bean 的 Id,返回的是对应的实现类
对应 xml配置文件 中的<bean id="xx"/>
还可以通过name属性指定bean的别名,比如@Bean(name = {"aa","bb"})

@Scope

声明作用域

@Value

前提是所有 @@PropertySource
使用 @Value 注解结合 spel 表达式进行值注入,也就是将 properties 文件中的属性值注入到当前字段中

@Value("${jdbc.driver}")

需要注入其他依赖的两种方式

通过参数注入(Spring进行注入)

@Bean
public UserController userController(UserService userService){
    return new UserController(userService);
}

通过其他的bean方法注入

@Bean
public UserController userController(){
    return new UserController(userService());
}

案例

@Configuration
@ComponentScan(basePackages = "edu.nf.ch13")
public class AppConfig {

    /**
     * 除了使用@Component、@Service、@Controller
     * @Respository注解来装配Bean以外,还可以使用
     * @Bean注解在配置类中装配Bean,这种方式很类似
     * 在xml中配置一个个的<bean id="xx"/>,
     * 用了@Bean注解后默认标注的方法名就是Bean的id,
     * 还可以通过name属性指定bean的别名
     *
     * @return
     */
    //@Bean(name = {"aa","bb"})
    @Bean
    public UserService userService() {
        return new UserServiceImpl();
    }

    /**
     * 当需要注入其他Bean的时候,有两种方式
     * 方式一:通过参数实现注入
     * 方式二:通过调用方bean方法实现注入
     *
     * @Scope注解还可以声明在Bean方法上来设置Bean的作用域
     * @return
     */
    @Bean
    @Scope("prototype")
    public UserController userController() {
        return new UserController(userService());
    }

}