@Scope
用于指定一个Bean的生命周期。
-
@Scope
注解的作用相当于xml配置中的scope
属性
<!--scope的默认是-->
<bean id="person" class="com.sff.app.bean.Person" scope="prototype"/>
-
ConfigurableBeanFactory.SCOPE_SINGLETON
:表示单实例的对象,在spring容器启动的时候创建,以后每次获取时都从容器中取。
@Configuration
public class AppConfig2 {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public Person person() {
System.out.println("给spring ioc容器中添加bean");
return new Person("Mate", 12);
}
}
用单元测试获取bean
public void test02() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);
System.out.println("spring ioc容器启动完成");
Person person = (Person) ctx.getBean("person");
Person person1 = (Person) ctx.getBean("person");
//==比较两个对象的地址值
System.out.println(person == person1);
}
运行结果:
给spring ioc容器中添加bean
spring ioc容器启动完成
true
我们获取了Person对象两次,但Person对象往容器中只添加了一下;
-
ConfigurableBeanFactory.SCOPE_PROTOTYPE
:多实例的,容器启动的时候不会创建Bean,每次调用Bean的创建方法都会创建一个实例Bean。
@Configuration
public class AppConfig2 {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person person() {
System.out.println("给spring ioc容器中添加bean");
return new Person("Mate", 12);
}
}
用单元测试获取bean
public void test02() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);
System.out.println("spring ioc容器启动完成");
Person person = (Person) ctx.getBean("person");
Person person1 = (Person) ctx.getBean("person");
//==比较两个对象的地址值
System.out.println(person == person1);
}
运行结果:
spring ioc容器启动完成
给spring ioc容器中添加bean
给spring ioc容器中添加bean
false
@Lazy
懒加载,针对的是单实例的Bean,容器启动的时候不创建对象,第一次获取Bean的时候创建并初始化对象。
@Configuration
public class AppConfig2 {
@Lazy
@Bean
public Person person() {
System.out.println("给spring ioc容器中添加bean");
return new Person("Mate", 12);
}
}
单元测试:
public void test02() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);
System.out.println("spring ioc容器启动完成");
ctx.getBean("person");
}
运行结果:
spring ioc容器启动完成
给spring ioc容器中添加bean
@Conditional
按照一定条件进行判断,满足条件就给容器注册Bean。
- 可以注解在Bean方法,表示满足当前条件,这个Bean的注册才生效。
- 可以注解在配置类上,表示满足当前条件,这个配置类中的所有Bean注册才能生效。
假如现在要根据当前操作系统类型注入一个Person对象,如果是Mac OS就注入乔布斯,如果是Windows系统就注入比尔盖茨。
/*配置类*/
@Configuration
public class AppConfig2 {
/*配置一个乔布斯*/
@Bean("Steve Jobs")
public Person appleFounder() {
return new Person("Steve Jobs", 40);
}
/*配置一个比尔盖茨*/
@Bean("Bill Gates")
public Person winFounder() {
return new Person("Bill Gates", 37);
}
}
自定义注入条件,实现Condition
接口
/**
* mac环境时注入条件
*/
public class MacCondition implements Condition {
/**
* @param context 判断条件能使用的上下文
* @param metadata 注释信息
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
/*获取容器使用的beanFactory*/
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
/*获取类加载器*/
ClassLoader classLoader = context.getClassLoader();
/*获取bean定义的注册类*/
BeanDefinitionRegistry registry = context.getRegistry();
/*获取当前的环境信息*/
Environment environment = context.getEnvironment();
if (environment.getProperty("os.name").contains("Mac")) {
return true;
}
return false;
}
}
/**
* windows时注入条件
*/
public class WinCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
/*获取当前的环境信息*/
Environment environment = context.getEnvironment();
if (environment.getProperty("os.name").contains("Win")) {
return true;
}
return false;
}
}
单元测试:
public void test03() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);
/*获取所有的bean*/
Map<String, Person> beansOfType = ctx.getBeansOfType(Person.class);
System.out.println(beansOfType);
}
运行结果中只注入了乔布斯,因为当前的开发环境时Mac OS:
{Steve Jobs=Person(name=Steve Jobs, age=40)}