Bean注册Bean依赖注入Bean生命周期- 资源属性赋值
Bean 注册
注册Bean的常用注解有@Component、@Service、@Controller、@Repository,通过扫描包的方式对这些注解进行解析注册Bean。
注解
ApplicationContext:AnnotationConfigApplicationContext
常用注解
@Configuration
声明Bean Difinition的配置文件,相当于一个xml文件
@Bean
声明Bean的组件
@Configuration
public class CustomConfig {
@Bean
public Person person() {
return new Person();
}
}
相当于xml bean内容
<beans>
<bean id="person" class="top.felixfly.entity.Person"/>
</beans>
bean的名称默认为方法名称,也可以通过
@Bean(value="person")或者@Bean("person")进行指定
@ComponentScan
指定扫描路径
@Configuration
@ComponentScan("top.felixfly.spring.annotation")
public class ScanConfiguration {
}
相当于xml component-scan
<beans>
<context:component-scan package="top.felixfly.spring.annotation"/>
</beans>
@ComponentScans
多个扫描路径,值为ComponentScan的数组,1.8以后可以用多个@ComponentScan代替此注解
@Scope
指定Bean的作用域,默认为singleton
singletonorg.springframework.beans.factory.config.ConfigurableBeanFactory#SCOPE_SINGLETONprototypeorg.springframework.beans.factory.config.ConfigurableBeanFactory#SCOPE_PROTOTYPErequestorg.springframework.web.context.WebApplicationContext#SCOPE_REQUESTsessionorg.springframework.web.context.WebApplicationContext#SCOPE_SESSION
@Configuration
public class CustomConfig {
@Bean
@Scope("singleton")
public Person person() {
return new Person();
}
}
相当于xml中bean中scope属性
<beans>
<bean id="person" class="top.felixfly.entity.Person" scope="singleton"/>
</beans>
@Lazy
懒加载,针对singleton Bean进行懒加载,默认情况下单实例Bean直接加载
@Configuration
public class CustomConfig {
@Bean
@Lazy
public Person person() {
return new Person();
}
}
相当于xml中bean的lazy-init属性
<beans>
<bean id="person" class="top.felixfly.entity.Person" lazy-init="true"/>
</beans>
@DependsOn
依赖关系注解
@Configuration
public class CustomConfig {
@Bean
@DependsOn("person")
public Manager manager(){
return new Manager();
}
@Bean
public Person person(){
return new Person();
}
}
相当于xml中bean的depends-on属性
<beans>
<bean id="manager" class="top.felixfly.entity.Manager" depends-on="person"/>
</beans>
@Order
Bean的排序,或者说是优先级,两个接口org.springframework.core.Ordered以及org.springframework.core.PriorityOrdered,主要使用优先级的内容
org.springframework.beans.factory.config.BeanPostProcessororg.springframework.http.converter.HttpMessageConverter
@Conditional
条件装配Bean
-
实现
org.springframework.context.annotation.Condition接口public class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// true 进行装配,false不进行装配
return false;
}
} -
Bean上配置@Conditional(Condition.class)@Configuration
public class CustomConfig {
@Conditional(CustomCondition.class)
@Bean
public Person person() {
return new Person();
}
}
当matches方法返回true的时候进行注册当前@Bean,否则不注册。该注解也可以放到配置类上,matches方法返回true的时候进行注册当前配置类,否侧不注册。
@Profile
环境注 解,底层使用的是@Conditional
@Import
快捷注册Bean,默认名称为类的全路径
-
直接导入类
@Configuration
@Import(Person.class)
public class CustomConfig {
} -
导入实现
org.springframework.context.annotation.ImportSelector类public class CustomImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{Person.class.getName()};
}
}@Configuration
@Import(CustomImportSelector.class)
public class CustomConfig {
} -
导入实现
org.springframework.context.annotation.ImportBeanDefinitionRegistrar类public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
// 自行注册BeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class);
registry.registerBeanDefinition("person",beanDefinition);
}
}@Configuration
@Import(CustomImportBeanDefinitionRegistrar.class)
public class CustomConfig {
}
@ImportResource
导入资源xml文件
资源文件名称
spring/application-spring.xml
<beans>
<bean class="top.felixfly.spring.annotation.entity.Person">
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" value="27"/>
</bean>
</beans>
@Configuration
@ImportResource("classpath:/spring/application-spring.xml")
public class CustomConfig {
}
常见问题
@Configuration、其他注解与@Bean结合使用有什么不同
答:@Configuration注解使用的其实也是一个Bean,但本身是BeanFatory,是经过CGLIB进行增强的Bean,其他注解(@Component、@Service、@Controller、@Repository)使用的就是一个简单的Bean
Bean 依赖注入
常用注解
@Autowired
Spring自带的自动注入,注解的属性required来支持是否必须要进行依赖注入。根据以下规则进行查找进行注入
- 根据类型查找,只查询一个直接返回
- 根据名称查找
@Service
public class PersonService {
@Autowired
private PersonMapper personMapper;
}
可以结合以下注解进行使用
-
@Qualifier指定名称进行依赖注入
@Service
public class PersonService {
@Autowired
@Qualifier("personMapper")
private PersonMapper personMapper;
} -
@Primary指定优先进行依赖注入
@Service
public class PersonService {
@Autowired
private PersonMapper personMapper;
}@Configuration
@ComponentScan({"top.felixfly.spring.annotation.mapper","top.felixfly.spring.annotation.service"})
public class CustomConfig {
// 优先注入
@Bean("personMapper2")
@Primary
public PersonMapper personMapper(){
return new PersonMapper();
}
}
只有一个有参构造器时,
@Autowired可以省略,可以自动进行注入
@Resource
Java规范(JSR250)的注解,默认按照属性的名称进行依赖查找匹配,也可以用属性name进行强制指定,但不支持与@Primary注解结合使用和required是否必须要进行依赖注入
@Service
public class PersonService {
@Resource
private PersonMapper personMapper;
}
@Service
public class PersonService {
// 强制指定Bean
@Resource(name="personMapper2")
private PersonMapper personMapper;
}
@Inject
Java规范的注解(JSR330),功能与@Autowired一样,但不支持required是否必须要进行依赖注入。需要引入javax.inject
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
@Service
public class PersonService {
@Inject
private PersonMapper personMapper;
}
注入方式
构造器注入
@Configuration
public class AppConfig {
@Bean
public BeanOne beanOne() {
// 构造器注入
return new BeanOne(beanTwo());
}
@Bean
public BeanOne beanThree(BeanTwo beanTwo) {
// 构造器注入
return new BeanOne(beanTwo);
}
@Bean
public BeanTwo beanTwo() {
return new BeanTwo();
}
}