spring註解驅動--組件註冊

  • 爲容器中註冊Bean

  • @Configuration表明該類是一個配置類,配置類起到的做用和xml配置文件同樣
  • @Bean表明該方法的返回對象做爲Bean加入IOC容器,默認Bean的id是方法的名稱。能夠在@Bean註解裏更改value的值來更更名稱
@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

  • excludeFilters是一個Filter類型的數組,因此這裏用大括號。每個Filter元素包含過濾條件的類型以及具體的過濾條件。以下面的Filter類型爲註解,過濾條件爲Controller。
@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; } }
  • includeFilters,配置只掃描哪些類型,多用於SpringMVC容器中只掃描controller註解,用法同XML配置,須要禁用默認過濾規則
@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

 

按照條件註冊Bean

  默認狀況下被標註了@Configuration的類下全部標註@Bean的方法返回對象都會被加入Spring容器中,使用@Conditional註解能夠自定義規則來只把某些Bean加入Spring容器中。插件

   實現Condition接口中的matches方法。conditionContext包含了一個Bean全部的信息code

  • beanFactory,建立該Bean的工程
  • classLoader,該Bean的類加載器
  • enviroment,該Bean所處的環境,主要指的是OS的環境
  • register,該Bean所處的容器

  下面的代碼實現兩個功能:一、打印該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 

  在配置類上方標註@Import註解並聲明要導入的類,會自動加到Spring中。

@Import({otherPojo.class, otherPojo2.class}) public class mainConfig {

 

ImportSelector

  使用上和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

  實現FactoryBean接口重寫getObject方法,並用@Bean方式加入Configuration中,則getObject返回的對象會加入Spring容器中

相關文章
相關標籤/搜索