一、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(); }
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 模式。
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 { }
二、依赖管理
配置类同样是一个 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