javascript
玩转Spring——Spring IOC/DI
什么是IOC
ioc :Inversion of Control,即控制反轉(zhuǎn)。
它不是一種技術(shù),而是一種設(shè)計(jì)思想,即java程序中獲取對象的方式發(fā)生反轉(zhuǎn),由最初的new方式創(chuàng)建,轉(zhuǎn)變成由第三方框架創(chuàng)建、注入。有了IoC容器后,把創(chuàng)建和查找依賴對象的控制權(quán)交給了容器,由容器進(jìn)行注入組合對象,所以對象與對象之間是 松散耦合,這樣也方便測試,利于功能復(fù)用,更重要的是使得程序的整個(gè)體系結(jié)構(gòu)變得非常靈活。
IOC是Spring 的框架的基礎(chǔ)和核心,貫穿整個(gè)Spring,其實(shí)IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發(fā)生了“主從換位”的變化。
也就是說我們自己不new來創(chuàng)建對象 而是把對象的創(chuàng)建權(quán)利交給Spring容器。
什么是DI
DI:Dependency Injection,譯為依賴注入。
依賴注入的目的并非為軟件系統(tǒng)帶來更多功能,而是為了提升組件重用的頻率,并為系統(tǒng)搭建一個(gè)靈活、可擴(kuò)展的平臺。通過依賴注入機(jī)制,我們只需要通過簡單的配置,而無需任何代碼就可指定目標(biāo)需要的資源,完成自身的業(yè)務(wù)邏輯,而不需要關(guān)心具體的資源來自何處,由誰實(shí)現(xiàn)。
也就是給對象和屬性賦值的過程。
依賴注入的方式
實(shí)現(xiàn)依賴注入主要有兩種方式:
1、setter注入
通過調(diào)用無參構(gòu)造器或者無參static工廠方法實(shí)例化bean以后,調(diào)用該Bean的set方法,即可實(shí)現(xiàn)setter注入。
2、構(gòu)造器注入
通過調(diào)用帶參數(shù)的構(gòu)造器來實(shí)現(xiàn),容器會在Bean被實(shí)例化的時(shí)候,根據(jù)參數(shù)的類型,執(zhí)行相應(yīng)的構(gòu)造器。
<!--index下標(biāo)要與構(gòu)造方法的形參順序一致,并且配置的constructor_arg標(biāo)簽要與形參個(gè)數(shù)一樣,不能多也不能少 -->
注意:如果要注入的是一個(gè)對象的話,需要先在xml中配置實(shí)例化這個(gè)bean,然后再在property元素中注入,其中注入的值得元素不再是value,而是ref。
通過<list/> <set/>和 <map/>實(shí)現(xiàn)集合元素的注入
<bean id="eb" class="value.ExampleBean"> <property name="interest"> <list> <value>釣魚</value> <value>蹦極</value> <value>跑酷</value> </list> <property name="city"> <set> <value>北京</value> <value>成都</value> <value>廈門</value> </set> </property> <property name="score"> <map> <entry key="math" value="150"/> <entry key="English" value="20"/> </map> </property> </bean>?
通過<props/> 可以實(shí)現(xiàn)對Properties類型參數(shù)值的注入
<bean id="eb" class="value.DButil"> <property name="properties"> <props> //每個(gè) <props> 可以嵌套多個(gè) <prop> , <prop> 內(nèi)部沒有任何元素可以使用,只能是字符串 <prop key="driver">com.mysql.jdbc.Driver</prop> <prop key="url">jdbc:mysql://localhost:3306/test</prop> </props> </property> </bean> public class DButil{ private Properties properties; //直接將上述值注入進(jìn) Properties 實(shí)例中,Properties實(shí)例就能得到對應(yīng)的key-value值 public void setDb(Properties properties) { this.db= db; } }?
Spring的util標(biāo)簽
開發(fā)者可以使用<list/>、<map/>、<set/>等元素定義集合,然而這些集合不能夠在不同的受管Bean間進(jìn)行復(fù)用,后來,<util/>命名空間被Spring 2.x引入,使得集合的定義變得簡單 ,比如<util:list>、 <util:set> 、<util:map>、<util:properties>
需要注意的是如果要使用util標(biāo)簽,則需要在頭文件添加兩句配置:
和在xsi:schemaLocation里面添加:
"http://www.springframework.org/schema/util" "http://www.springframework.org/schema/util/spring-util-3.2.xsd" <!-- 給該list定義命名空間 ,方便多個(gè)bean復(fù)用--> <util:list id="interestBean"> <value>書法</value> <value>旅游</value> </util:list> <util:properties id="dbBean"> <prop key="driver">com.mysql.jdbc.Driver</prop> <prop key="url">jdbc:mysql://localhost:3306/gokee_0703</prop> </util:properties> <!-- 將定義好的 list 和 properties對象注入 --> <bean id="eb2" class="value.ExampleBean"> <property name="interest" ref="interestBean"/> <property name="db" ref=“dbBean”> </bean>?
Spring表達(dá)式(SpEL)
SpEL是一種強(qiáng)大的、簡潔的裝配Bean的方式,它通過運(yùn)行期執(zhí)行的表達(dá)式將值裝配到Bean的屬性或構(gòu)造器參數(shù)中。我們可以在<property>元素的value屬性中使用#{}界定符將值裝配到Bean的屬性中。比如:
?
利用SpEL向指定bean注入xxx.properties文件的信息
<!--location屬性自動(dòng)加載配置xxx.properties,并且注冊成對應(yīng)bean --> <util:properties id="config" location="config.properties"/> <bean id="dbutil" class="first_spring.DButil"> <property name="driver" value="#{config.driver}"/> <property name="url" value="#{config.url}"/> <property name="userName" value="#{config.userName}"/> <property name="password" value="#{config.password}"/> </bean>?
Spring注解掃描過程
spring容器啟動(dòng)之后,如果發(fā)現(xiàn)配置文件當(dāng)中包含了 component-scan的配置信息,則spring容器會掃描指定包及其 子包下面的所有的類;如果這些類包含了一些特定的注解,則容器會將其納入容器進(jìn)行管理。相當(dāng)于在配置文件當(dāng)中,添加了一個(gè)bean 的配置。
對于掃描到的這些組件(類),Spring會對他們有默認(rèn)的取名策略,即類名首字母小寫。
一般來說Spring的注解可以分為兩大類:
1、和Spring的bean容器相關(guān)的注解
2、 SpringMVC相關(guān)的注解
Spring相關(guān)注解
1、bean實(shí)例創(chuàng)建的注解(有以下注解的類會被自動(dòng)注冊成bean 跟在配置文件寫bean一樣的效果):
@Component : 通用注解,是所有受Spring 管理組件的通用形式,但是一般來說不推薦使用該注解
@ Service: 業(yè)務(wù)層(service )注解
@ Repository : 數(shù)據(jù)持久層注解(DAO)
@controller : web /controller的注解
具體使用步驟:
步驟1:在配置文件中applicationContext.xml配置文件書寫
<context:component-scan base-package="要掃描的包名"/>
這里還需要添加兩個(gè)jar包:
spring-aop-4.2.4.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar
步驟2:在想要實(shí)例化的類前加上注解
@Component public class UserBean{ } 添加了注解以后該類就會被Spring自動(dòng)實(shí)例化
注: 當(dāng)一個(gè)組件在掃描過程中被檢測到時(shí),會為該類生成一個(gè)默認(rèn)的id標(biāo)示值,一般值為類名小寫,我們也可以在注解標(biāo)記中自定義該值:
?
測試類:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserBean user=(UserBean)ac.getBean("userInfo"); System.out.println("用戶信息: "+user);?
依賴注入相關(guān)注解
1、@Autowire(重點(diǎn)) 和 @Qualaifier
這兩個(gè)注解既支持set方式注入,也支持構(gòu)造器注入set方式注入,將 @Autowire 放在set方法前,或者添加到屬性前,@Qualifier作用是知道要被注入bean的id,按byName注入如果不指定按照byType的方式注入,構(gòu)造器用法同上 ,實(shí)際應(yīng)用中還是推薦直接寫在屬性上,不用調(diào)用構(gòu)造器或set方法。
2、@Inject 和 @Named
?用法同第一個(gè)
3、@Resource (重點(diǎn))
只支持set方式注入,后面可以加一個(gè)name屬性 ,即 @Resource(name="要注入bean的id"), 不加則按照byType方法注入, 該注解加在set方法前,也可加在屬性值前
注:set注入推薦使用 @Resource 構(gòu)造器注入推薦使用 @Autowire
其他注解:
1、關(guān)于生命周期的兩個(gè)注解:
(1)@PostConstruct 初始化注解
(2)@PreDestroy 銷毀注解
注意:這兩個(gè)注解都是寫在方法前面的,不是在類前面,不然會報(bào)錯(cuò)
2、作用域的注解
@Scope("prototype") 多例
3、延時(shí)加載的注解
@Lazy(true) 延時(shí)
4、賦值的注解
@Value
它的的兩個(gè)用法:
4.1.注入基本類型的值,
4.2.可以用該注解來使用spring表達(dá)式,該注解可以寫在set方法前,也可在屬性前。
@Value("#{config.pagesize}") public void setPageSize(String pageSize) { this.pageSize = pageSize; }用spring表達(dá)式來獲取config.proerties里的值,再寫入 Vlaue("xxx"),注入給pageSize。
實(shí)際開發(fā)中使用XML還是注解?
XML:bean管理
注解:注入屬性的時(shí)候比較方便.
兩種方式結(jié)合;一般使用XML注冊Bean,使用注解進(jìn)行屬性的注入。
?
轉(zhuǎn)載于:https://www.cnblogs.com/ericz2j/p/10908947.html
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的玩转Spring——Spring IOC/DI的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法:动态数组(利用万能指针实
- 下一篇: gradle idea java ssm