@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)}