@Configuration public class mainConfig { @Bean("person") public Person person01(){ Person person = new Person(); person.setId(1); person.setName("aa"); return person; } }
ComponentScan配置掃描哪些包,用法和xml配置文件中的包掃描相同,包含可配置的excludeFilter和includeFilter選項。spring
@Configuration @ComponentScan(value = "comtroller",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)}) public class mainConfig { @Bean("person") public Person person01(){ Person person = new Person(); person.setId(1); person.setName("aa"); return person; } }
@Configuration @ComponentScan(value = "comtroller",includeFilters = {@ComponentScan.Filter(type=FilterType.ANNOTATION,classes=Controller.class)},useDefaultFilters = false) public class mainConfig { @Bean("person") public Person person01(){ Person person = new Person(); person.setId(1); person.setName("aa"); return person; } }
只添加或者只過濾某個具體的類數組
@ComponentScan(value = "comtroller",excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = BookController.class)})
查看包掃描是否生效就是查看Spring容器裏是否有想要的Bean。緩存
方法一:打印出Spring容器中全部Bean。簡單粗暴。ide
public class test { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(mainConfig.class); String[] names = context.getBeanDefinitionNames(); for (String name: names) { System.out.println(name); } } }
方法二:藉助idea。每新配置一個Spring容器,不管是經過xml仍是配置類方式,最好都配置idea的spring管理插件,這樣能夠沒必要運行測試類也可查看容器裏的Bean測試
並且在配置生效的狀況下@Component註解旁邊會多一個符號,點擊該符號能夠跳轉到掃描的包。idea
Spring中的Bean默認是單例,且在容器加載的時候就被初始化。使用@Scope改變爲多實例,對應的Bean在每次getBean的時候都會初始化一次,因此Bean在容器啓動的時候不會初始化。背後的邏輯是單例模式是Spring容器維護了一個緩存HashMap,而多實例下並無這個緩存。既然沒有緩存那麼在多實例狀況下就沒法存儲初始化以後的Bean。spa
@Bean("person") @Scope("prototype") public Person person01(){ Person person = new Person(); person.setId(1); person.setName("aa"); return person;
針對單實例狀況下容器建立時Bean就會被建立,使用@Lazy能夠實現對單實例Bean在getBean的時候才加載。prototype
默認狀況下被標註了@Configuration的類下全部標註@Bean的方法返回對象都會被加入Spring容器中,使用@Conditional註解能夠自定義規則來只把某些Bean加入Spring容器中。插件
實現Condition接口中的matches方法。conditionContext包含了一個Bean全部的信息code
下面的代碼實現兩個功能:一、打印該Bean所處容器內全部的Bean 二、判斷該Bean所處OS的類型,若是是Win就返回true即把Bean注入到容器中
public class WinCondition implements Condition { /** * * @param conditionContext 環境上下文 * @param annotatedTypeMetadata 註釋信息 * @return */ public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); ClassLoader classLoader = conditionContext.getClassLoader(); Environment environment = conditionContext.getEnvironment(); //得到容器對象,進而判斷容器中Bean的註冊狀況 BeanDefinitionRegistry registry = conditionContext.getRegistry(); String[] names = registry.getBeanDefinitionNames(); System.out.println("===="); for (String name : names) { System.out.println(name); } String osName = environment.getProperty("os.name"); if (osName.contains("Win")){ return true; } return false; } }
最後要把註解標註在方法或者配置類上。由於個人系統不是Win系統因此容器裏沒有zhangsan這個Bean。
@Conditional({WinCondition.class}) @Bean("zhangsan") public Person person_01(){ return new Person("zhangsan",12); }
在配置類上方標註@Import註解並聲明要導入的類,會自動加到Spring中。
@Import({otherPojo.class, otherPojo2.class}) public class mainConfig {
使用上和Import相似,經過實現ImportSelector接口能夠按照條件批量註冊Bean,其中return的String數組中的Bean會被註冊到Spring中。
public class importSelect implements ImportSelector { /** * @param annotationMetadata 當前標註Import類的所有註解信息,不單單是Import * @return 要導入容器的類的全類名 */ public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"pojo.otherPojo2"}; } }
@Import(importSelect.class) public class mainConfig
Import註解是標註着配置類上的,ImportSelector中的AnnotationMetadata包含配置類全部註解的信息,經過打斷點能夠看到以下的結果。
實現FactoryBean接口重寫getObject方法,並用@Bean方式加入Configuration中,則getObject返回的對象會加入Spring容器中