之前寫了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