spring框架:
1.spring是一個輕量級的控制反轉和面向切面aop的容器框架
控制反轉:ioc

核心容器:
1.應用上下文 context模塊:
2.aop模塊:
3.jdbc抽象和dao模塊
4.對象關系映射集成模塊
5.spring web模塊
6.spring mvc框架
spring ioc控制反轉和di依賴注入
ioc:即控制反轉,不是什么技術,而是一種設計思想,在JAVA開發(fā)中,ioc意味著將你設計好的對象交給容器控制,而不是傳統(tǒng)的在你的對象內(nèi)部直接控制;在傳統(tǒng)java se的程序設計,為們直接在對象內(nèi)部通過new進行創(chuàng)建對象,是程序主動去創(chuàng)建依賴對象;而ioc是有專門的一個容器來創(chuàng)建這些對象,即由ioc容器來控制對象的創(chuàng)建;
反轉:傳統(tǒng)應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫助創(chuàng)建及注入依賴對象;因為由容器幫我們查找及注入依賴對象,對象只是被動的接受依賴對象,所以是反轉;依賴對象的獲取被反轉了。
ioc能做什么:
ioc不是一種技術,只是一種思想。一個重要的面向?qū)ο缶幊痰姆▌t,它能指導我們?nèi)绾卧O計出松耦合,更優(yōu)良的程序,傳統(tǒng)應用程序都是由我們在類內(nèi)部主動創(chuàng)建依賴對象,從而導致類與類之間高耦合,難于測試;有了ioc容器后,吧創(chuàng)建和查找依賴對象的控制交給了容器;有容器進行諸如組合對象,所以對象與對象之間是松散耦合,這樣也方便測試,利于功能復用,更重要的是使得程序的整個體系結構變得非常靈活。
其實IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發(fā)生了“主從換位”的變化。應用程序原本是老大,要獲取什么資源都是主動出擊,但是在IoC/DI思想中,應用程序就變成被動的了,被動的等待IoC容器來創(chuàng)建并注入它所需要的資源了。
IoC很好的體現(xiàn)了面向?qū)ο笤O計法則之一—— 好萊塢法則:“別找我們,我們找你”;即由IoC容器幫對象找相應的依賴對象并注入,而不是由對象主動去找。
ioc和di:
di-dependency injection 即 ‘依賴注入’ 組件之間依賴關系由容器在運行期決定,形象的說,即由容器動態(tài)將某個依賴注入到組件之中,依賴注入的目的并非為軟件系統(tǒng)帶來更多功能,而是為提升組件重要的頻率,并為系統(tǒng)搭建一個靈活,可擴展的平臺,通過依賴注入機制,我們只需要通過簡單的配置,而無需要任何代碼就可指定目標需要的資源,完成自身的業(yè)務邏輯,而不需要關系具體的資源來自何處,由誰實現(xiàn)。
“依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”
spring bean工廠和工廠bean 分析
bean工廠:不是bean,在spring中一般指的是DefaultListableBeanFactory對象,管理和維護spring中所有的bean
工廠bean:一種特殊的bean,在xml文件中配置的,用來生成新的bean的加工廠,通過getObject()方法可以獲取其生產(chǎn)的新bean,如果想獲取該工廠bean本身,需要使用類似于getBean("&" + beanName)的樣式。
<bean name="studentFactory" class="com.demo.StudentFactoryBean" />
Spring常用的三種注入方式
1.構造方法注入:
2.setter注入:
3.基于注解的注入:
構造方法注入:
在spring的配置文件中注冊UserService,將UserDaoJdbc通過constructor-arg標簽注入到UserService的某個有參數(shù)的構造方法 <!-- 注冊userService --> <bean id="userService" class="com.lyu.spring.service.impl.UserService"> <constructor-arg ref="userDaoJdbc"></constructor-arg> </bean> <!-- 注冊jdbc實現(xiàn)的dao --> <bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
通過name屬性指定要注入的值,與構造方法參數(shù)列表參數(shù)的順序無關。 <!-- 注冊userService --> <bean id="userService" class="com.lyu.spring.service.impl.UserService"> <constructor-arg name="userDao" ref="userDaoJdbc"></constructor-arg> <constructor-arg name="user" ref="user"></constructor-arg> </bean> <!-- 注冊實體User類,用于測試 --> <bean id="user" class="com.lyu.spring.entity.User"></bean> <!-- 注冊jdbc實現(xiàn)的dao --> <bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>
基于注解的注入:
bean的一個屬性autowire,autowire主要有三個屬性值:constructor,byName,byType。
constructor:通過構造方法進行自動注入,spring會匹配與構造方法參數(shù)類型一致的bean進行注入,如果有一個多參數(shù)的構造方法,一個只有一個參數(shù)的構造方法,在容器中查找到多個匹配多參數(shù)構造方法的bean,那么spring會優(yōu)先將bean注入到多參數(shù)的構造方法中。
byName:被注入bean的id名必須與set方法后半截匹配,并且id名稱的第一個單詞首字母必須小寫,這一點與手動set注入有點不同。
byType:查找所有的set方法,將符合符合參數(shù)類型的bean注入。
注解方式注冊bean,注入依賴
主要有四種注解可以注冊bean,每種注解可以任意使用,只是語義上有所差異:
@Component:可以用于注冊所有bean
@Repository:主要用于注冊dao層的bean
@Controller:主要用于注冊控制層的bean
@Service:主要用于注冊服務層的bean
描述依賴關系主要有兩種:
1.@Resource
2.@Autowired
@Resource java的注解,默認以byName的方式去匹配與屬性名相同的bean的id,如果沒有找到就會以byType的方式查找,如果byType查找到多個的話,使用@Qualifier注解(spring注解)指定某個具體名稱的bean。
@Resource @Qualifier("userDaoMyBatis") private IUserDao userDao; public UserService(){ }
@Autowired:spring注解,默認是以byType的方式去匹配類型相同的bean,如果只匹配到一個,那么就直接注入該bean,無論要注入的 bean 的 name 是什么;如果匹配到多個,就會調(diào)用 DefaultListableBeanFactory 的 determineAutowireCandidate 方法來決定具體注入哪個bean。determineAutowireCandidate 方法的內(nèi)容如下:
determineAutowireCandidate 方法的邏輯是:
先找 Bean 上有@Primary 注解的,有則直接返回 bean 的 name。
再找 Bean 上有 @Order,@PriorityOrder 注解的,有則返回 bean 的 name。
最后再以名稱匹配(ByName)的方式去查找相匹配的 bean。
可以簡單的理解為先以 ByType 的方式去匹配,如果匹配到了多個再以 ByName 的方式去匹配,找到了對應的 bean 就去注入,沒找到就拋出異常。
還有一點要注意:如果使用了 @Qualifier 注解,那么當自動裝配匹配到多個 bean 的時候就不會進入 determineAutowireCandidate 方法(親測),而是直接查找與 @Qualifer 指定的 bean name 相同的 bean 去注入,找到了就直接注入,沒有找到則拋出異常。
tips:大家如果認真思考可能會發(fā)現(xiàn) ByName 的注入方式和 @Qualifier 有點類似,都是在自動裝配匹配到多個 bean 的時候,指定一個具體的 bean,那它們有什么不同呢?
ByName 的方式需要遍歷,@Qualifier 直接一次定位。在匹配到多個 bean 的情況下,使用 @Qualifier 來指明具體裝配的 bean 效率會更高一下。
spring 支持三種創(chuàng)建bean
1.調(diào)用構造器創(chuàng)建bean;
2.調(diào)用靜態(tài)工廠方法創(chuàng)建bean;
3.調(diào)用實例工廠方法創(chuàng)建bean;
ioc底層原理:dom4j+反射
反射一定會走無參構造函數(shù);
反射原理 加載配置xml配置文件,解析xml文件,bean的幾點, 初始化bean id class=是全路徑;
拿到beanid 去容器中
spring容器的 bean的作用域:
1.singleton:這種bean范圍是默認的,這種范圍確保不管接受到多少個請求,每個容器中只有一個bean的實例,單例的模式由bean factory自身來維護;
2.prototype:原型范圍與單例范圍相反,為每一個bean請求提供一個實例;
3.request:在請求bean范圍內(nèi)會每一個來自客戶端的網(wǎng)絡請求創(chuàng)建一個實例,在請求完成以后,bean會消失并被垃圾回收;
4.session:與請求范圍類似,確保每一個session中有一個bean的實例,在session過期后,bean會隨之失效;
5.global_session: global_session 和portlet應用相關,當你的應用部署在portlet容器中工作時,他包含很多portlet,如果你想要聲明讓所有的portlet公用全局的存儲的話,那么這全局變量需要存儲在global_session中。
springmvc 和 struts2比較

1.springMVC的入口是servlet,而struts2是filter;
2.springmvc 會比struts2快些,springmvc是基于方法設計,而sturt2是基于類,每次發(fā)一次請求都會實例一個action;
3.springmvc 使用更加簡潔,開發(fā)效率springmvc比struts2高;
spring 事務管理器:
spring并不是直接管理事務,而是提供了多種事務管理器,他們將事務管理的職責委托給hibernate或者jta等待持久化機制所提供的相關平臺框架的事務來實現(xiàn);
spring 事務: 1.編程式事務控制; jdbc代碼 hibernate事務
聲明事務:spring 聲明式事務管理,核心實現(xiàn)就是基于aop
spring聲明式是為管理類:
jdbc技術:DataSourceTransactionManager
Hibernate技術:HibernateTransationManager
spring session

web.xml 配置filter: springSessionRepositoryFilter
spring的七種事物傳播行為:
PROPAGATION_REQUIRED 如果當前沒有事務,就新建一個事務,如果已經(jīng)存在一個事務中,加入到這個事務中。這是最常見的選擇。
PROPAGATION_SUPPORTS 支持當前事務,如果當前沒有事務,就以非事務方式執(zhí)行。
PROPAGATION_MANDATORY 使用當前的事務,如果當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW 新建事務,如果當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED 以非事務方式執(zhí)行操作,如果當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER 以非事務方式執(zhí)行,如果當前存在事務,則拋出異常。
PROPAGATION_NESTED 如果當前存在事務,則在嵌套事務內(nèi)執(zhí)行。如果當前沒有事務,則執(zhí)行與PROPAGATION_REQUIRED類似的操作。
aop底層實現(xiàn)原理:
代理設計模式:通過代理控制對象的訪問,可以想象訪問某個對象方法,在這個方法調(diào)用處理,或者調(diào)用后處理,aop的核心技術面相切面編程;
@Aspect 指定一個類為切面類
@Pointcut("execution(* com.itmayiedu.service.UserService.add(..))") 指定切入點表達式
@Before("pointCut_()") 前置通知: 目標方法之前執(zhí)行
@After("pointCut_()") 后置通知:目標方法之后執(zhí)行(始終執(zhí)行)
@AfterReturning("pointCut_()")返回后通知: 執(zhí)行方法結束前執(zhí)行(異常不執(zhí)行)
@AfterThrowing("pointCut_(_()") 異常通知: 出現(xiàn)異常時候執(zhí)行
@Around("poinrcut_()") 環(huán)繞通知:環(huán)繞目標方法執(zhí)行
@before("execution(* com.muth.service.userservece.add(..))")