IOC: 控制反轉(zhuǎn)
即控制權(quán)的轉(zhuǎn)移,將我們創(chuàng)建對象的方式反轉(zhuǎn)了,以前對象的創(chuàng)建時由我們開發(fā)人員自己維護(hù),包括依賴關(guān)系也是自己注入。使用了spring之后,對象的創(chuàng)建以及依賴關(guān)系可以由spring完成創(chuàng)建以及注入,反轉(zhuǎn)控制就是反轉(zhuǎn)了對象的創(chuàng)建方式,從我們自己創(chuàng)建反轉(zhuǎn)給了程序創(chuàng)建(spring)
DI: Dependency Injection 依賴注入
spring這個容器中,替你管理著一系列的類,前提是你需要將這些類交給spring容器進(jìn)行管理,然后在你需要的時候,不是自己去定義,而是直接向spring容器索取,當(dāng)spring容器知道你的需求之后,就會去它所管理的組件中進(jìn)行查找,然后直接給你所需要的組件.
實現(xiàn)IOC思想需要DI做支持
注入方式: 1.set方式注入 2.構(gòu)造方法注入 3.字段注入
注入類型: 1.值類型注入 2.引用類型注入
好處:
1.降低組件之間的耦合度,實現(xiàn)軟件各層之間的解耦.
2.可以使容器提供眾多服務(wù)如事務(wù)管理消息服務(wù)處理等等。當(dāng)我們使用容器管理事務(wù)時,開發(fā)人員就不需要手工 控制事務(wù),也不需要處理復(fù)雜的事務(wù)傳播
3.容器提供單例模式支持,開發(fā)人員不需要自己編寫實現(xiàn)代碼.
4.容器提供了AOP技術(shù),利用它很容易實現(xiàn)如權(quán)限攔截,運行期監(jiān)控等功能
5.容器提供眾多的輔佐類,使這些類可以加快應(yīng)用的開發(fā).如jdbcTemplate HibernateTemplate
BeanFactory接口
(1) spring的原始接口,針對原始接口的實現(xiàn)類功能較為單一
(2)BeanFactory接口實現(xiàn)類的容器,特點是每次在獲得對象時才會創(chuàng)建對象
ApplicationContext接口
(1)每次容器啟動時就會創(chuàng)建容器中配置的所有對象
(2)提供了更多功能
(3)從類路徑下加載配置文件: ClassPathXmlApplicationContext
從硬盤的絕對路徑下加載配置文件:FileSystemXmlApplication
bean元素:使用該元素描述需要spring容器管理對象
name屬性:給被管理的對象起個名字,獲得對象時getBean('name值')
class屬性:被管理對象的完整類名
id屬性:與name屬性一模一樣,名稱不可重復(fù),不能使用特殊字符
name和id之間的一些注意點:
1、配置兩個相同的 id 或者 name 都不能通過。
2、如果既配置了 id ,也配置了 name ,則兩個都生效。如果id和name都沒有指定,則用類全名作為name,如<bean class='com.stamen.BeanLifeCycleImpl'>,則你可以通過getBean('com.stamen.BeanLifeCycleImpl')返回該實例。
3、如果配置基本類的時候,注解和配置文件都使用的時候,注解和配置文件中 name 相同的時候, 則兩個沖突,配置文件生效。
如果配置基本類的時候,注解和配置文件都使用的時候,注解和配置文件中 name 不相同的時候, 則兩個不沖突,都能夠生效。
(1)scope屬性
(1)singleton 默認(rèn)值
單例對象 :被標(biāo)識為單例的對象在spring容器中只會存在一個實例
(2)prototype
多例原型:被標(biāo)識為多例的對象,每次在獲得才會被創(chuàng)建,每次創(chuàng)建都是新的對象
(3)request
Web環(huán)境下,對象與request生命周期一致
(4)session
Web環(huán)境下,對象與session生命周期一致
總結(jié):絕大多數(shù)情況下,使用單例singleton(默認(rèn)值),但是在與struts整合時候,務(wù)必要用prototype多例,因為struts2在每次請求都會創(chuàng)建一個新的Action,若為單例,在多請求情況下,每個請求找找spring拿的都是同一個action。
(2)生命周期屬性(了解)———初始化和銷毀
(1)配置一個方法作為生命周期初始化方法,spring會在對象創(chuàng)建之后立刻調(diào)用 init-method
(2)配置一個方法作為生命周期的銷毀方法,spring容器在關(guān)閉并銷毀所有容器中的對象之前調(diào)用destory-method
<bean init-method=“init” destory-method=“destory”></bean> 對應(yīng)注解為@PostConstruct
<bean name=“hello” class=“完整類名”></bean> 對應(yīng)注解為@PreDestory
(3)模塊化配置,即分模塊配置(導(dǎo)入其他spring配置文件)
<beans>
<import resource = “spring配置文件的全路徑名” />
</beans>
<bean name='user' class='cn.itcats.UserFactory' factory-method='createUser'></bean>
<bean name='user2' factory-bean='userFactory' factory-method='createUser'></bean> <bean name=“userFactory” class=“cn.itcats.UserFactory”></bean>
函數(shù)注入
(3)p名稱空間注入———實際上set注入,spring特有,為了簡化<property>寫法
1、applicationContext.xml中<beans>標(biāo)簽頭部導(dǎo)入p命名空間
xmlns:p='http://www.springframework.org/schema/p'
2、書寫格式:值類型注入—— p:屬性名='值' 引用類型注入—— p:屬性名-ref='引用的<bean> name屬性'
把Run類中的name屬性值設(shè)置為haha,age屬性設(shè)置為20,引用屬性hello引用<bean name='hello' class='...'></bean>
<bean name='run2' class='cn.itcats.thread.Run' p:name='haha' p:age='20' p:hello-ref='hello'></bean>
(4)spel注入: spring Expression Language spring表達(dá)式語言
<bean name='runSpel' class='cn.itcats.thread.Run'> <!-- 取bean標(biāo)簽中name為'user'中property為'name'中的value值 --!> <property name='name' value='#{user.name}'></property></bean>
SpEL特性:(1)、使用Bean的ID來引用Bean;(2)、調(diào)用方法和訪問對象的屬性;(3)、對值進(jìn)行算術(shù)、關(guān)系和邏輯運算;(4)、正則表達(dá)式匹配;(5)、集合操作
關(guān)于spel https://www.cnblogs.com/goodcheap/p/6490896.html
復(fù)雜類型注入
1、需要導(dǎo)入包spring-web
2、在web.xml中配置監(jiān)聽器
注意:假如不寫括號內(nèi)的值(即name或id),默認(rèn)使用類名首字母小寫作為搜索,為什么意思呢?
比如Student類中使用了@Component 沒有書寫括號和值,那么默認(rèn)搜索id或name為student。
聲明Student類對象為多例 下面是對singleton和prototype的一些補充
singleton作用域:當(dāng)把一個Bean定義設(shè)置為singleton作用域是,Spring IoC容器中只會存在一個共享的Bean實例,并且所有對Bean的請求,只要id與該Bean定義相匹配,則只會返回該Bean的同一實例。值得強調(diào)的是singleton作用域是Spring中的缺省作用域。
prototype作用域:prototype作用域的Bean會導(dǎo)致在每次對該Bean請求(將其注入到另一個Bean中,或者以程序的方式調(diào)用容器的getBean()方法)時都會創(chuàng)建一個新的Bean實例。根據(jù)經(jīng)驗,對有狀態(tài)的Bean應(yīng)使用prototype作用域,而對無狀態(tài)的Bean則應(yīng)該使用singleton作用域。對于具有prototype作用域的Bean,有一點很重要,即Spring不能對該Bean的整個生命周期負(fù)責(zé)。具有prototype作用域的Bean創(chuàng)建后交由調(diào)用者負(fù)責(zé)銷毀對象回收資源。簡單的說:
singleton 只有一個實例,也即是單例模式。
prototype訪問一次創(chuàng)建一個實例,相當(dāng)于new。
實際通過反射field賦值
實際通過set方式賦值
面試題: @AutoWired和@Resource的區(qū)別?
@AutoWired默認(rèn)以類型進(jìn)行查找,@Resource默認(rèn)以名稱進(jìn)行查找
@AutoWired(required=false) + @Qualifier('user') == @Resource(name='user')
其中@Resource注解是jdk1.6后才有的
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration('classpath:applicationContext.xml')
JoinPoint(連接點):目標(biāo)對象中,所有可以增強的方法,就是spring允許你是通知(Advice)的地方,那可就真多了,基本每個方法的前、后(兩者都有也行),或拋出異常是時都可以是連接點,spring只支持方法連接點。
Pointcut(切入點):目標(biāo)對象中,已經(jīng)被增強的方法。調(diào)用這幾個方法之前、之后或者拋出異常時干點什么,那么就用切入點來定義這幾個方法。
Advice(通知/增強) :增強方法的代碼、想要的功能。
Target(目標(biāo)對象):被代理對象,被通知的對象,被增強的類對象。
Weaving(植入):將通知應(yīng)用到連接點形成切入點的過程
Proxy(代理):將通知植入到目標(biāo)對象之后形成的代理對象
aspect(切面):切入點+通知————通知(Advice)說明了干什么的內(nèi)容(即方法體代碼)和什么時候干(什么時候通過方法名中的before,after,around等就能知道),二切入點說明了在哪干(指定到底是哪個方法),切點表達(dá)式等定義。
雖然現(xiàn)在都用Maven項目構(gòu)建,但是不能忘記,使用aop需要用到的包:spring-aop + spring-aspects + springsource.org.aopalliance + springsource.org.aspectj.weaver
關(guān)于AOP看一個小例子:
1、準(zhǔn)備目標(biāo)對象(被代理對象,被通知的對象,被增強的類對象)
2、準(zhǔn)備通知(被增強方法的代碼,想要實現(xiàn)功能的方法代碼)
3、配置 applicationContext.xml
1.導(dǎo)入aop(約束)命名空間
2.配置目標(biāo)對象
3.配置通知對象
4.配置將通知織入目標(biāo)對象
4、測試
總結(jié):通知的幾種類型
1.前置通知———目標(biāo)方法運行之前調(diào)用
2.后置通知———目標(biāo)方法運行之后調(diào)用(如果出現(xiàn)異常不調(diào)用)
3.環(huán)繞通知———目標(biāo)方法之前和之后都調(diào)用
4.異常攔截通知———如果出現(xiàn)異常,就會調(diào)用
5.后置通知———目標(biāo)方法運行之后調(diào)用(無論是否出現(xiàn)異常都會調(diào)用)
1、applicationContext.xml中配置目標(biāo)對象,通知對象,開啟使用注解完成織入
2、@Aspect注解代表該類是個通知類,書寫切點表達(dá)式@Pointcut('execution(返回值 全類名.方法名(參數(shù)))')
注意環(huán)繞通知需要這么寫:
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //環(huán)繞方法執(zhí)行前 //proceedingJoinPoint.proceed();表示對攔截的方法進(jìn)行放行 //若注釋proceedingJoinPoint.proceed()則不會執(zhí)行被AOP匹配的方法proceedingJoinPoint.proceed(); //環(huán)繞方法執(zhí)行后}
AOP注解解析:
@Before 前置通知(Before advice) :在某連接點(JoinPoint)——核心代碼(類或者方法)之前執(zhí)行的通知,但這個通知不能阻止連接點前的執(zhí)行。為啥不能阻止線程進(jìn)入核心代碼呢?因為@Before注解的方法入?yún)⒉荒軅鱌roceedingJoinPoint,而只能傳入JoinPoint。要知道從aop走到核心代碼就是通過調(diào)用ProceedingJionPoint的proceed()方法。而JoinPoint沒有這個方法。
這里牽扯區(qū)別這兩個類:Proceedingjoinpoint 繼承了 JoinPoint 。是在JoinPoint的基礎(chǔ)上暴露出 proceed 這個方法。proceed很重要,這個是aop代理鏈執(zhí)行的方法。暴露出這個方法,就能支持 aop:around 這種切面(而其他的幾種切面只需要用到JoinPoint,這跟切面類型有關(guān)), 能決定是否走代理鏈還是走自己攔截的其他邏輯。建議看一下 JdkDynamicAopProxy的invoke方法,了解一下代理鏈的執(zhí)行原理。這樣你就能明白 proceed方法的重要性。@After 后通知(After advice) :當(dāng)某連接點退出的時候執(zhí)行的通知(不論是正常返回還是異常退出)。
@AfterReturning 返回后通知(After return advice) :在某連接點正常完成后執(zhí)行的通知,不包括拋出異常的情況。
@Around 環(huán)繞通知(Around advice) :包圍一個連接點的通知,類似Web中Servlet規(guī)范中的Filter的doFilter方法??梢栽诜椒ǖ恼{(diào)用前后完成自定義的行為,也可以選擇不執(zhí)行。這是aop的最重要的,最常用的注解。用這個注解的方法入?yún)鞯氖荘roceedingJionPoint pjp,可以決定當(dāng)前線程能否進(jìn)入核心方法中——通過調(diào)用pjp.proceed();
@AfterThrowing 拋出異常后通知(After throwing advice) : 在方法拋出異常退出時執(zhí)行的通知。
spring中提供了一個可以操作數(shù)據(jù)庫的對象,對象封裝了jdbc技術(shù) ————JDBCTemplate JDBC模板對象,而JdbcDaoSupport則對JdbcTemplate進(jìn)行了封裝,所以要操作JdbcTemplate,或只需要繼承JdbcDaoSupport即可。
依賴關(guān)系配置:
測試:
事物的概述⑴ 原子性(Atomicity)
原子性是指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾,因此事務(wù)的操作如果成功就必須要完全應(yīng)用到數(shù)據(jù)庫,如果操作失敗則不能對數(shù)據(jù)庫有任何影響。
⑵ 一致性(Consistency)
一致性是指事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另一個一致性狀態(tài),也就是說一個事務(wù)執(zhí)行之前和執(zhí)行之后都必須處于一致性狀態(tài)。
拿轉(zhuǎn)賬來說,假設(shè)用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉(zhuǎn)賬,轉(zhuǎn)幾次賬,事務(wù)結(jié)束后兩個用戶的錢相加起來應(yīng)該還得是5000,這就是事務(wù)的一致性。
⑶ 隔離性(Isolation)
隔離性是當(dāng)多個用戶并發(fā)訪問數(shù)據(jù)庫時,比如操作同一張表時,數(shù)據(jù)庫為每一個用戶開啟的事務(wù),不能被其他事務(wù)的操作所干擾,多個并發(fā)事務(wù)之間要相互隔離。
即要達(dá)到這么一種效果:對于任意兩個并發(fā)的事務(wù)T1和T2,在事務(wù)T1看來,T2要么在T1開始之前就已經(jīng)結(jié)束,要么在T1結(jié)束之后才開始,這樣每個事務(wù)都感覺不到有其他事務(wù)在并發(fā)地執(zhí)行。
關(guān)于事務(wù)的隔離性數(shù)據(jù)庫提供了多種隔離級別,稍后會介紹到。
⑷ 持久性(Durability)
持久性是指一個事務(wù)一旦被提交了,那么對數(shù)據(jù)庫中的數(shù)據(jù)的改變就是永久性的,即便是在數(shù)據(jù)庫系統(tǒng)遇到故障的情況下也不會丟失提交事務(wù)的操作。
例如我們在使用JDBC操作數(shù)據(jù)庫時,在提交事務(wù)方法后,提示用戶事務(wù)操作完成,當(dāng)我們程序執(zhí)行完成直到看到提示后,就可以認(rèn)定事務(wù)以及正確提交,即使這時候數(shù)據(jù)庫出現(xiàn)了問題,也必須要將我們的事務(wù)完全執(zhí)行完成,否則就會造成我們看到提示事務(wù)處理完畢,但是數(shù)據(jù)庫因為故障而沒有執(zhí)行事務(wù)的重大錯誤。
關(guān)于事務(wù)的隔離級別我之前發(fā)布了一篇文章:https://blog.csdn.net/itcats_cn/article/details/81487466
spring中事務(wù)可以分為編程式事務(wù)控制和聲明式事務(wù)控制。
編程式事務(wù)控制
自己手動控制事務(wù),就叫做編程式事務(wù)控制。
Jdbc代碼:
Conn.setAutoCommit(false); // 設(shè)置手動控制事務(wù)
Hibernate代碼:
Session.beginTransaction(); // 開啟一個事務(wù)
【細(xì)粒度的事務(wù)控制: 可以對指定的方法、指定的方法的某幾行添加事務(wù)控制】
(比較靈活,但開發(fā)起來比較繁瑣: 每次都要開啟、提交、回滾.)
聲明式事務(wù)控制
Spring提供了對事務(wù)的管理, 這個就叫聲明式事務(wù)管理。
Spring提供了對事務(wù)控制的實現(xiàn)。用戶如果想用Spring的聲明式事務(wù)管理,只需要在配置文件中配置即可; 不想使用時直接移除配置。這個實現(xiàn)了對事務(wù)控制的最大程度的解耦。
Spring聲明式事務(wù)管理,核心實現(xiàn)就是基于Aop。
【粗粒度的事務(wù)控制: 只能給整個方法應(yīng)用事務(wù),不可以對方法的某幾行應(yīng)用事務(wù)?!?/p>
(因為aop攔截的是方法。)
Spring聲明式事務(wù)管理器類:
Jdbc技術(shù):DataSourceTransactionManager
Hibernate技術(shù):HibernateTransactionManager
有一點需要注意的:若為編程式事務(wù)控制,則開啟事務(wù)后一定要手動釋放(提交或回滾),否則長期占用內(nèi)存,有可能報事務(wù)異常
spring封裝了事務(wù)管理的代碼(打開,提交,回滾事務(wù))
事務(wù)操作對象,因為在不同平臺,操作事務(wù)的代碼各不相同.spring提供了一個接口
————— PlatformTransactionManager 接口
————— 在不同平臺,實現(xiàn)不同的接口即可
————— 注意:在spring中玩事務(wù)管理.最為核心的對象就是TransactionManager對象
spring管理事務(wù)的屬性介紹
(1)事務(wù)的隔離級別
(2)是否只讀
(3)事務(wù)的傳播行為
配置事務(wù)的核心管理器,它封裝了所有事務(wù),依賴于連接池(DataSourceTransactionManager)
xml中配置通知
配置將通知織入目標(biāo)
在需要管理的方法或者類中聲明配置事務(wù)管理
@Transactional(isolation=Isolation.REPEATABLE_READ,readOnly=false,propagation=Propagation.REQUIRED)
小編整理了一份Java基礎(chǔ)視頻、技術(shù)文檔、電子書、面試題、簡歷模板等福利分享給大家。