Spring基于Java配置的容器
一、Bean 管理 1. 元数据 2. Full 模式和 Lite 模式 3. 组合配置 4. 扫描类路径配置 二、依赖管理 1. 依赖注入 1.1 参数注入 1.2 方法注入 2. 依赖关系 3. 懒加载 三、附录 1. 常用注解 2. 示例代码
Spring 容器的元数据可以基于 Java 代码配置,它像 XML 配置一样不侵入源代码,同时也支持注解配置。
你可以在项目中任意选择哪种配置方式,或者多种方式共存。
一、Bean 管理
1. 元数据
基于 Java 配置 Bean,定义一个类并使用@Configuration
注解作为配置类,在类中的方法上使用@Bean
注解,就会注册一个以方法返回值为实例的 Bean。
@Configuration
public class AppConfig {
@Bean
public BeanExample beanExample() {
return new BeanExample();
}
@Bean
public BeanProvider beanProvider() {
return new BeanProvider();
}
}
默认使用方法名称作为 Bean 名称,也可以通过注解的value
或name
属性来指定。
使用AnnotationConfigApplicationContext
来实例化容器。
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
BeanExample beanExample = (BeanExample) applicationContext.getBean("beanExample");
}
Bean 作用域
使用@Scope
注解来指定 Bean 的作用域。
@Bean
@Scope("singleton")
public BeanExample beanExample() {
return new BeanExample();
}
作用域类型参阅《Spring基于XML配置的容器》
2. Full 模式和 Lite 模式
一般情况下,@Bean
用于@Configuration
注解的类下,这种方式为 Full 模式。
当@Bean
用于其他注解(如@Component
)的类下,或者为任何一个 Bean 内部的方法,这种情况为 Lite 模式。
// Full
@Configuration
public class AppConfig {
@Bean
public BeanExample beanExample() {
return new BeanExample();
}
}
// Lite
@Component
public class AppConfig {
@Bean
public BeanExample beanExample() {
return new BeanExample();
}
}
Full 模式会生成 CGLIB 代理类,可以通过方法调用来依赖其它 Bean。
Lite 模式则不生成,可以提高运行性能,降低启动时间。
为了避免方法调用注入依赖的 Bug,推荐在业务中使用 Full 模式,在组件工具封装中使用 Lite 模式。
Spring 5.2.x 版本后,
@Configuration
可以指定属性proxyBeanMethods
为 false,来禁用 CGLIB 进入 Lite 模式。
3. 组合配置
为了实现模块化配置,可以定义多个配置类,在配置类中使用@Import
注解来导入其他配置类。
在实例化容器的时候,只需要指定AppConfig
类,不需要指定所有配置类。
@Configuration
public class OtherConfig {
@Bean
public BeanProvider beanProvider() {
return new BeanProvider();
}
}
@Configuration
@Import(OtherConfig.class)
public class AppConfig {
@Bean
public BeanExample beanExample(BeanProvider beanProvider) {
BeanExample beanExample = new BeanExample();
beanExample.setBeanProvider(beanProvider);
return beanExample;
}
}
4. 扫描类路径配置
使用@ComponentScan
来配置扫描的包路径,支持基于注解配置。
@Configuration
@ComponentScan(basePackages = "cn.codeartist.spring.bean.java")
public class AppConfig {
}
参阅上一篇《Spring基于注解配置的容器》
二、依赖管理
配置类同样是一个 Bean,也支持字段注入、构造器注入和 Setter 方法注入依赖。
@Configuration
public class AppConfig {
@Autowired
private BeanProvider beanProvider;
@Bean
public BeanExample beanExample() {
BeanExample beanExample = new BeanExample();
beanExample.setBeanProvider(beanProvider);
return beanExample;
}
}
1. 依赖注入
1.1 参数注入
依赖的 Bean 可以通过方法参数注入。
@Bean
public BeanExample beanExample(BeanProvider beanProvider) {
BeanExample beanExample = new BeanExample();
beanExample.setBeanProvider(beanProvider);
return beanExample;
}
1.2 方法注入
在同一个配置类中,可以直接调用方法来依赖其它 Bean,该方式只在生成 CBLIB 代理类的 Full 模式下才生效。
@Configuration
public class AppConfig {
@Bean
public BeanExample beanExample() {
BeanExample beanExample = new BeanExample();
beanExample.setBeanProvider(beanProvider());
return beanExample;
}
@Bean
public BeanProvider beanProvider() {
return new BeanProvider();
}
}
2. 依赖关系
使用@DependsOn
注解指定依赖关系。
@Bean
@DependsOn("beanProvider")
public BeanExample beanExample() {
return new BeanExample();
}
3. 懒加载
使用@Lazy
注解配置懒加载。
@Lazy
@Bean
public BeanProvider beanProvider() {
return new BeanProvider();
}
懒加载 Bean 在注入的地方也要加上@Lazy
注解,或者使用ApplicationContext.getBean()
方法获取 Bean,才能使懒加载生效。
@Bean
public BeanExample beanExample(@Lazy BeanProvider beanProvider) {
BeanExample beanExample = new BeanExample();
beanExample.setBeanProvider(beanProvider);
return beanExample;
}
三、附录
1. 常用注解
注解 | 描述 |
---|---|
@Configuration | 指定 Bean 的配置类 |
@Bean | 配置 Bean 元数据,作用于方法上,方法返回值作为 Bean 实例 |
@Scope | 指定 Bean 的作用域 |
@Import | 导入其他配置类 |
@DependsOn | 指定 Bean 的依赖关系 |
@Lazy | 配置懒加载 |
2. 示例代码
Gitee 仓库:
https://gitee.com/code_artist/spring
项目模块:
spring-ioc
示例路径:
cn.codeartist.spring.bean.java