第3章-Spring基于注解配置的容器

Spring 容器的元数据可以基于注解配置,它比 XML 配置更简洁,而且提供了更多的上下文配置。

两种配置方式各有优缺点,XML 配置不会侵入源代码,配置修改后不需要重新编译源文件。

你可以在项目中任意选择哪种配置方式,或者两者混合使用。

参阅上一篇《Spring基于XML配置的容器

一、Bean 管理

Spring 通过扫描指定包路径下所有的类(包括子包下的类),来寻找哪些类是要容器管理的。

默认情况下,根据类是否存在 @Component 注解(或其组合注解)来判断是否由容器管理。

1. 扫描类路径配置

基于 XML 配置

在 XML 配置文件中使用 context:component-scan 来配置扫描的包路径。

<beans>

    <context:component-scan base-package="cn.codeartist.spring.bean.annotation"/>

</beans>

使用 ClassPathXmlApplicationContext 来实例化容器。

public static void main(String[] args) {
    ApplicationContext applicationContext =
        new ClassPathXmlApplicationContext("bean-annotation.xml");
    BeanExample beanExample = (BeanExample) applicationContext.getBean("beanExample");
}

基于注解配置

定义类并使用 @Configuration@ComponentScan 来配置扫描的包路径。

@Configuration
@ComponentScan(basePackages = "cn.codeartist.spring.bean.annotation")
public class AppConfig {

}

@ComponentScan 可以不指定 basePackages,默认扫描类(AppConfig)所在的包路径。

使用 AnnotationConfigApplicationContext 来实例化容器。

public static void main(String[] args) {
    ApplicationContext applicationContext =
        new AnnotationConfigApplicationContext(AppConfig.class);
    BeanExample beanExample = (BeanExample) applicationContext.getBean("beanExample");
}

2. 使用注解管理 Bean

在扫描的包下面,在类上面使用 @Component 注解来注册 Bean。

@Component
public class BeanExample {

    private String name;
    private Integer year;

    // Getter and setter
}

为了更明确 Bean 的业务用途,体现项目的分层结构,Spring 还提供了 @Service@Repository@Controller 等注解。

这些注解默认使用类名小驼峰格式作为 Bean 名称,也可以通过注解的 value 属性来指定。

BeanExample -> beanExample

Bean 作用域

使用 @Scope 注解来指定 Bean 的作用域。

@Component
@Scope("singleton")
public class BeanExample {

    private String name;
    private Integer year;
}

作用域类型参阅《Spring基于XML配置的容器

二、依赖管理

在基于 XML 配置容器中,使用 context:annotation-config 来配置注解注入。

<beans>

    <context:annotation-config/>

</beans>

如果 XML 配置文件中存在 context:component-scan,则不需要配置 context:annotation-config

Spring 通常使用 @Autowired@Resource 注解注入 Bean 依赖,@Autowired 注解默认通过类型注入。

@Resource 注解默认通过名称注入,只有匹配不到对应名称的 Bean,才会按类型注入。

1. 依赖注入

1.1 字段注入

直接在字段上面使用注解注入依赖。

@Component
public class BeanExample {

    private String name;
    private Integer year;

    @Autowired
    private BeanProvider beanProvider;
}

1.2 构造器注入

在构造器方法上使用注解注入依赖。

@Component
public class BeanExample {

    private String name;
    private Integer year;
    private BeanProvider beanProvider;

    @Autowired
    public BeanExample(BeanProvider beanProvider) {
        this.beanProvider = beanProvider;
    }
}

Spring 4.3.x 版本后,构造器注入可以不用写注解。

1.3 Setter 方法注入

在 Setter 方法上使用注解注入依赖。

@Component
public class BeanExample {

    private String name;
    private Integer year;
    private BeanProvider beanProvider;

    @Autowired
    public void setBeanProvider(BeanProvider beanProvider) {
        this.beanProvider = beanProvider;
    }
}

2. 依赖关系

使用 @DependsOn 注解指定依赖关系。

@Component
@DependsOn("beanProvider")
public class BeanExample {

    private String name;
    private Integer year;
    private BeanProvider beanProvider;

    // Getter and setter
}

3. 懒加载

使用 @Lazy 注解配置懒加载。

@Lazy
@Component
public class BeanProvider {

    // Fields

    // Getter and setter
}

懒加载 Bean 在注入的地方也要加上 @Lazy 注解,或者使用 ApplicationContext.getBean() 方法获取 Bean,才能使懒加载生效。

@Component
public class BeanExample {

    private String name;
    private Integer year;
    
    @Lazy
    @Autowired
    private BeanProvider beanProvider;
}

三、附录

1. 配置属性

属性 描述
context:component-scan 在基于 XML 配置容器中,指定扫描包路径
context:annotation-config 在基于 XML 配置容器中,启用注解注入依赖

2. 常用注解

注解 描述
@Configuration 指定 Bean 的配置类
@ComponentScan (默认为类所在的包)指定包路径,该包下的类由容器管理
@Component 指定该类由 Spring 容器管理
@Service @Component 一致,通常在业务层使用
@Repository @Component 一致,通常在数据层使用
@Controller @Component 一致,通常在控制层使用
@Autowired 配置自动注入,优先通过类型注入
@Resource 配置自动注入,优先通过名称注入
@Scope 指定 Bean 的作用域
@DependsOn 指定 Bean 的依赖关系
@Lazy 配置懒加载

3. 示例代码

Gitee 仓库:

https://gitee.com/code_artist/spring

项目模块:

spring-ioc

示例路径:

cn.codeartist.spring.bean.annotation

posted @ 2022-11-27 15:55  码匠_CodeArtist  阅读(26)  评论(0编辑  收藏  举报