Spring註解驅動開發——設定Bean屬性和動態註冊Bean
1、@Scope設定元件作用域
@Configuration
public class MainConfigA {
@Bean("person")
@Scope("singleton")
public Person person(){
return new Person("張三丰",25);
}
}
public class JuitTest { @Test public void test(){ ApplicationContext context = new AnnotationConfigApplicationContext(MainConfigA.class); Person person = (Person)context.getBean("person"); Person person1 = (Person)context.getBean("person"); System.out.print(person == person1);//true } }
@Scope的值:
singleton:單例,預設值,每次都返回同一個物件,該物件是在容器啟動的時候建立的,在使用的時候直接從容器中獲取
prototype:多例項,每次都新建立一個物件,物件不會在容器啟動時建立,而是在獲取物件時建立,每次獲取都建立一個新物件
request:一個請求範圍內只建立一個物件
session:一次會話範圍內只建立一個物件
@Scope註解也可以在元件的類名上標註:
@Component @Scope("prototype") public class Person { public Person() { System.out.println("Person Constructor"); } }
@Scope("prototype") public class Person { public Person() { System.out.println("Person Constructor"); } }
2、@Lazy註解實現元件Bean的懶載入
單例項的Bean物件預設在容器啟動的時候建立,可以設定懶載入使Bean的建立時機延後至第一次獲取的時候建立和初始化,懶載入僅作用於單例項(singleton)的Bean
@Configuration @ComponentScan(value="com.bdm",useDefaultFilters = false,includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM,classes = {BdmTypeFilter.class})}) public class MainConfig { @Bean @Lazy public Person person() { return new Person("lisi", 12); } }
3、@Conditional:按照條件動態註冊Bean
public class JunitTest{
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
public void test(){
Map<String,Person> persons = context.getBeansOfType(Person.class);
System.out.print(persons);
ConfigurableEnvironment environment = context.getEnvironment();//獲取執行環境
String osName = environment.getProperty("os.name");//獲取作業系統名稱
}
}
從這個測試類獲取Bean的方式可以看出Spring容器是將Bean的物件放在了Map中,而且同一個型別的bean可能會有多個(id不同),id為key、bean為value,另外通過ApplicationContenxt的物件可以獲取當前的執行環境資訊,在呼叫context.getBeansOfType(Person.class)方法時會建立所有型別為Person的物件
使用@Conditional註解需自定義Condition:實現Condition介面
public class MyCondition implements Condition {
// context:判斷條件使用的上下文
// metaData:使用該註解的類的註解資訊
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 執行時的資訊以及環境變數、虛擬機器的變數
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.toLowerCase().contains("Windows"))
return true;
// // 建立和裝配Bean的工廠
// ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// // 類載入器
// ClassLoader classLoader = context.getClassLoader();
// // 所有的bean定義都在該類中註冊 也可以使用該物件註冊Bean
// BeanDefinitionRegistry registry = context.getRegistry();
return false;
}
}
容器Bean中使用@Conditional註解:使person類僅會在windows系統中才會建立
@Configuration
public class MainConfig {
@Bean
@Conditional({MyCondition.class})
public Person person(){
return new Person("張三",12);
}
@Bean
public Person person1(){
return new Person("李四",13);
}
}
@Conditional({MyCondition.class})
public Person person(){
return new Person("張三",12);
}
@Bean
public Person person1(){
return new Person("李四",13);
}
}
@Conditional註解可以標註在配置類上也可以標註在@Bean註解的方法上,作用的範圍不同,標註在類上時影響整個容器Bean
@Conditional的值是一個Condition型別的陣列,Condition是一個介面,有一個matches方法,該方法中有兩個引數:
ConditionContext:通過此型別的引數可以獲取執行環境、Bean工廠等資訊
AnnotatedTypeMetadata:通過此型別的變數可獲取到使用@Conditional註解的類的註解資訊