一、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; }
在基于 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; } }
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