本节中,主要阐述说明IOC容器中,组件(bean)添加、赋值标签的使用,以及Bean创建核心接口
bean的作用域(scope)
作用域 | 含义 | 说明 | 是否初始化 |
---|---|---|---|
singleton | 单例 | 每次调用都是同一个实例(默认项) | 是 |
prototype | 多例 | 每次调用都会生成新实例 | 否 |
request | request域多例 | 每一次request请求对象中,创建一次 | 否 |
session | session域多例 | 每一个session会话对象中,创建一次 | 否 |
globalSession | 全局session多例 | 每一个全局session会话对象中,创建一次(只在porlet的web应用程序中才有意义。普通的web应用使用该scope,将被当作普通的session域创建) | 否 |
在组件添加对象为单例,并且不预先初始化
可以使用@Lazy
(懒加载)
该实例将在被调用时再加载
声明一个bean为多例
@Scope("prototype")
@Service
public class UserService {
}
组件添加
对于常见组件添加标签如下所示:
@Configuration 声明类为配置类,该类管理bean的添加与配置工作。
@Bean 针对普通pojo类
@Service 针对业务层归类的bean
@Repository 针对持久层归类的bean,对应Dao层
@Component 对于不好归类的bean则可以使用该标签,泛指组件
@Controller 针对控制层归类的bean
@Restcontroller 针对控制层归类的bean(相当于@Controller+@ResponseBody结合,不解析视图,若有前端返回,则对象序列化结果)
配合条件标签使用,用来灵活处理bean是否应该被添加
@Conditional(xxxConditionImpl.class)
按条件添加,需要实现一个继承Condition接口的类,并且在match中实现添加判断逻辑
组件添加延伸,实现多个bean组件灵活添加
- @Import与@Configuration结合使用,能够快速导入多个bean,避免逐个标记注解(默认bean的id为全类名)
@Import({ xx1.class, xx2.class })
@Configuration
public class Config(){...}
- 实现
ImportSelector
接口方式,灵活实现多个bean组件引入。
@Import({ xxxSelectImports.class })
@Configuration
public class Config(){...}
......
public class xxxSelectImports implements ImportSelector {
String[] selectImports(){
return new String[]{ "xx1.class", "xx2.class" }
}
}
- 实现
ImportBeanDefinitionRegistrar
接口方式,灵活实现多个bean组件引入。
public class BeanRegistry implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
// 将目标类转为BeanDefinition类后添加入IOC容器中
RootBeanDefinition definition = new RootBeanDefinition(User.class);
beanDefinitionRegistry.registerBeanDefinition("heavent", definition);
}
}
组件赋值
常用的组件赋值标签
1. 引入指定路径位置的属性文件
@PropertySource("path")
2. 通过EL表达式,将属性文件中的变量信息赋值给变量,例如存在```app.author=heavent```配置信息:
@Value("${app.author}")
String name;
另外如果并没有配置app.author变量参数,在编译期将会异常,可以顺带声明默认值避免编译异常:
默认为空字符
@Value("${app.author:}")
默认为字符串
@Value("${app.author:heavent}")
默认为整型值25
@Value("${app.author:25}")
默认为布尔值false
@Value("${app.author:false}")
3. 如果存在多个同类的bean实例添加,区分哪个实例会被优先添加的方式:
@Primary
声明bean实例在被注入时,优先选中
一般与@Bean配合使用,在bean声明添加阶段时使用
@Qualifier
指定bean的id进行赋值(若指定的id未配置,则会报空异常)
一般与@Autowired配合使用,在bean指定赋值阶段时使用
两种标签同时存在,则@Qualifier优先级更高
@Autowired(required=false)
required默认为true,当设置为false时则允许IOC不存在实例时也不报错
同级别标签,作用类似于@Autowired,JSR250标准
@Resource(name="bean id")
不支持@Primary声明
声明的实例必须在IOC容器中已存在,否则报错
同级别标签, 不依赖Spring, 需引入第三方的包javax.inject, JSR330标准
@Inject
支持@Primary声明
声明的实例必须在IOC容器中已存在,否则报错