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
最新文章关注 CodeArtist 码匠公众号。