Spring Boot之注解下的IOC

之前寫了Springboot的一些入門,至于怎么搭建SpringBoot項(xiàng)目,網(wǎng)上一大堆,就不再闡述了。
ICO:控制反轉(zhuǎn),依賴注入,對(duì)于IOC的概念,大家已經(jīng)滾瓜爛熟了,這里不再多加闡述(Spring最成功的就是IOC和AOP這兩個(gè)核心理念,所以思想值得學(xué)習(xí),原理搞清楚會(huì)對(duì)自己幫助很大)
IOC比較簡(jiǎn)單,這里簡(jiǎn)單總結(jié)一些重要的知識(shí)點(diǎn)

  • IOC的定義:ioc是一種通過描述生成或者獲取對(duì)象的技術(shù)

  • IOC的兩個(gè)基本功能:

    • 通過描述管理Bean,包括發(fā)布和獲取Bean
    • 通過描述完成Bean之間的依賴關(guān)系
  • IOC容器都需要實(shí)現(xiàn)的頂級(jí)容器接口:BeanFactory

    Package org.springframework.beans.factory;
    import org.springframework.beans.BeansException;
    improt org.springframework.core.ResolvableType;
    public interface BeanFactory{
        // 前綴
        String FACTORY_BEAN_PREFIX="&";  
    /**
        返回指定BeanName(或別名)的Bean
        對(duì)Protorype:每次返回不同的實(shí)例
        對(duì)Singleton:每次返回相同的實(shí)例
    */
        Object getBean(String name) throws BeansException;
        
    /**
        返回同時(shí)匹配指定BeanName(或別名)和類型的Bean
        對(duì)Protorype:每次返回不同的實(shí)例
        對(duì)Singleton:每次返回相同的實(shí)例
    */
        <T> T getBean(String name, Class<T> requiredType) throws BeansException;
        /**
        返回指定BeanName(或別名)的Bean,并把所提供的參數(shù)作為構(gòu)造函數(shù)參數(shù)或工廠方法參數(shù)初始化Bean
        對(duì)Protorype:每次返回不同的實(shí)例
        對(duì)Singleton:拋出BeanDefinitionStoreException異常
    */
        Object getBean(String name, Object... args) throws BeansException;
    /**
        返回指定類型的Bean,如果存在多個(gè)bean定義有相同的類型,則拋NoUniqueBeanDefinitionException異常
        對(duì)Protorype:每次返回不同的實(shí)例
        對(duì)Singleton:每次返回相同的實(shí)例
    */
        <T> T getBean(Class<T> requiredType) throws BeansException;
        
        /**
        返回指定類型的Bean,并把所提供的參數(shù)作為構(gòu)造函數(shù)參數(shù)或工廠方法參數(shù)初始化Bean
        對(duì)Protorype:每次返回不同的實(shí)例
        對(duì)Singleton:拋出BeanDefinitionStoreException異常
    */
        <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
        /**
        返回一個(gè)ObjectProvider<T>該類型允許對(duì)Bean處于not available情況和not-unique情況時(shí)做處理
    */
        <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
    /**
        作用同上
    */
        <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
        /**
        根據(jù)指定的BeanName或別名判斷factory是否包含bean定義(concrete
         or abstract, lazy or eager, in scope or not)或由外部注冊(cè)的單例,
        返回true時(shí)并不保證一定能通過getBean獲取相應(yīng)實(shí)例(eg: 抽象Bean)
    */
        boolean containsBean(String name);
    
    /**
        根據(jù)指定的BeanName或別名判斷factory中該Bean的scope是否是Singleton
        返回false時(shí)不代表scope是prototype(使用自定義的scope時(shí))
    */
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    /**
        根據(jù)指定的BeanName或別名判斷factory中該Bean的scope是否是Prototype
        返回false時(shí)不代表scope是Singleton(使用自定義的scope時(shí))
    */
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
    /**
        根據(jù)指定的BeanName或別名判斷factory中該Bean的類型是否與提供的類型匹配
    */
        boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    
    /**
        根據(jù)指定的BeanName或別名判斷factory中該Bean的類型是否與提供的類型匹配
    */
        boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
    /**
        根據(jù)指定的BeanName或別名獲取factory中該Bean的類型,對(duì)于FactoryBean類型,將調(diào)用它的
        getObjectType()
    */
        @Nullable
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
    /**
        根據(jù)指定的BeanName或別名返回factory中該Bean的別名,
        如果提供的時(shí)別名將返回BeanName和其他別名的數(shù)組,BeanName
        置與第一個(gè)元素
    */
        String[] getAliases(String name);
        
    }
    
    • isSingleton==true:單例模式 ,每次返回的都是同一個(gè)對(duì)象
    • isPrototype==true:每次使用getBean獲取對(duì)象時(shí),IOC容器就會(huì)創(chuàng)建一個(gè)新的Bean返回給調(diào)用者。
  • 注解:

    • @Bean:將bean注入到IOC容器中

    • @Component:哪個(gè)類被掃描進(jìn)入Spring IOC容器

    • @ComponentScan:表明采用何種策略去掃描裝配Bean,默認(rèn)只會(huì)掃描當(dāng)前包和其子包,但是也允許我們自定義掃描包

      • 配置項(xiàng)

        • basePackages:定義掃描的包名

        • basePackageClasses:定義掃描的類

        • includeFilters:定義滿足過濾器條件的Bean才去掃描

        • excludeFilters:排除過濾器條件的Bean

          注意:他們都需要通過一個(gè)注解@Filter去定義,他有一個(gè)type類型,這里可以定義為注解或者正則表達(dá)式等類型。classes定義注解類,pattern定義正則表達(dá)式。

          eg:不想掃描包下面的service類

          @ComponentScan(basePackages="com.springboot.*",
          excludeFilters={@Filter(classes={service.class})})
          
          • 所有標(biāo)注了@Service的類將不被IOC容器掃描注入
    • main方法在idea中的快捷鍵:psvm

    • springBoot的啟動(dòng):

      SpringApplication.run(主程序類.class,main函數(shù)的參數(shù));
      
    • Spring Boot將所有的功能場(chǎng)景都抽取出來,做成一個(gè)個(gè)的starter(啟動(dòng)器),只需要在項(xiàng)目里面引入這些starter,相關(guān)場(chǎng)景的所有依賴都會(huì)導(dǎo)入進(jìn)來

    • 自定義第三方Bean:現(xiàn)實(shí)的java應(yīng)用往往需要引入許多來自第三方的包,并且很有可能希望把第三方包的類對(duì)象也放入到Ioc容器中,這是@Bean注解就可以發(fā)揮作用了。

      eg:引入一個(gè)DBCP的數(shù)據(jù)源

      @Bean(name="dataSource")
      public DataSource getDataSource(){
         Properties pros=new Properties();
         pros.setProPerty("driver","com.mysql.jdbc.Driver");
         .....
         return dataSource;
      }
      

      說明:注解將會(huì)用“datasource”的名稱作為Bean名稱保存到IOC容器中

    • 依賴注入:@Autowired:會(huì)根據(jù)屬性的類型找到對(duì)應(yīng)的Bean進(jìn)行注入,如果對(duì)應(yīng)類型給的Bean不是唯一的,那么它會(huì)根據(jù)其屬性名稱和Bean的名稱進(jìn)行匹配,如果匹配得上,就會(huì)使用該Bean,如果還是無法匹配,就會(huì)拋出異常。

      注意:@Autowired是一個(gè)默認(rèn)必須找到對(duì)應(yīng)Bean的注解,如果不能確定其標(biāo)注屬性一定會(huì)存在,并且允許這個(gè)被標(biāo)注的屬性為null,則可以配置@Autowired的屬性required為false.eg:

      @Autowired(required=false)
      
  • Bean的生命周期:

    • Bean定義
    • Bean初始化
    • Bean的生存期
    • Bean銷毀
    資源定位 Bean定義 發(fā)布Bean定義 實(shí)例化 依賴注入
    例如@Component定義的掃描包 將Bean定義保存到BeanDefinition中 Ioc容易裝載Bean定義 創(chuàng)建Bean示例對(duì)象 例如@Autowired注入各類資源

    注意:默認(rèn)情況下Bean定義被發(fā)布到IOC容器之后,會(huì)繼續(xù)去完成初

    始化,但有些Bean會(huì)收到變化因素的影響,這時(shí)我們希望是取出Bean時(shí)完成初始化和依賴注入,此時(shí)可將Component的配置項(xiàng)lazyInit設(shè)為true

    @ComponentScan(basepackage="",lazyInit=true)
    
  • Bean作用域:

    作用域類型 使用范圍 作用域描述
    singleton 所有spring 應(yīng)用 默認(rèn)值,IOC容器中只存在單例
    prototype 所有spring 應(yīng)用 每當(dāng)從IOC容器中取出一個(gè)Bean,則創(chuàng)建一個(gè)新的Bean
    session Spring Web 應(yīng)用 Http會(huì)話
    application Spring Web 應(yīng)用 Web工程生命周期
    request Spring Web 應(yīng)用 web工程單次請(qǐng)求
    globalSession Spring Web 應(yīng)用 在一個(gè)全局的Http Session中,一個(gè)Bean對(duì)應(yīng)一個(gè)實(shí)例
  • spring.profile.active:配置環(huán)境

  • Spring EL表達(dá)語言:可以擁有更為強(qiáng)大的運(yùn)算規(guī)則來更好的裝配Bean

    @Value("${database.driverName}") 
    String driver;
    
    @Value("#{T(System).currentTimeMilis()}")
    private Long initTime=null;
    
    @Value("#{beanName.str}")
    private String otherBeanProp=null;
    
    @Value("#{beanName.str?.toUpperCase()}")
    private String ortherBeanProp=null;
    
    @Value("#{beanName.str eq 'springBoot'}")
    
    • ${......}代表占位符:會(huì)讀取上下文的屬性值裝配到屬性中
    • {......}代表啟動(dòng)Spring表達(dá)式:具有運(yùn)算功能

    • T(.......)代表引入類
    • beanName是spring Ioc容器Bean名稱,str是其屬性(獲取其他的Spring Bean 屬性來給當(dāng)前的Bean屬性賦值)
    • ?. :判斷這個(gè)屬性是否為null
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容