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

原文地址:http://www.cnblogs.com/code-artist/p/spring-3.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性