GIT地址:https://github.com/BravenZhou/spring-ioc-easy java
Spring容器框架,能夠管理web層,業務層,dao層,持久層。
能夠配置各個組件並維護bean之間的關係。當須要使用某個bean的時候 ,使用getBean方法便可
ApplicationContext對象就對應那個ApplicationContext。xml文件
1.使用Spring沒必要new對象 。咱們把建立對象的任務交給了spring框架。
2.在一個對象中,引用另一個bean。(即spring管理對象關係)用ref。mysql
spring框架怎麼被加載?spring中配置的bean怎麼被加載?bean關係如何維護?
ClassPathXMLApplicationContext被加載的時候,至關關鍵:它執行的時候,
spring容器對象被建立,同時applicationContext中配置的bean就會被建立。
內存中(結構是一個hashmap) :
id有你配置的id=,而後有對象的實例。
ApplicationContext.put("userService",userService);
須要獲取的時候就調用ac.getBean()方法便可
Dom4J是反射機制。git
ioc:所謂控制反轉,就是把建立對象和維護對象之間的關係的權利,
從程序中轉移到spring容器中(applicationContext.xml)。
di:spring設計者,認爲di更能準確表示spring核心技術。github
大的項目,行業不同。可是有不少可複用模塊,如日誌,等,之間配置就能夠了。
但這些屬於高級模塊,也仍是須要有底層的基礎。web
能夠寫一個applicationContextUtil的方法,直接調用getBean方法。redis
MVC:
model層:包括業務層,dao層,持久層(一個項目中不必定都有這三個)。
view層:jsp
Controller:Action。spring
spring提倡接口編程,DI技術能夠層與層之間的解耦。
UserService userService = ac.getBean("userService");
//一樣一行代碼,若是有兩個類須要實現UserService對象時,只需更改配置
<bean id="userService" class="com.UserService1Impl"/>
切換爲--> <bean id="userService" class="com.UserService2Impl"/>
spring用到代理技術。
springXML文件中的bean是不能寫class=接口的,只能寫具體的實現類。
接口編程的優點就在這裏:當有多個不同的類實現同一個接口時,可用接口來實現。
這樣Controller層對於Service層就徹底解耦了,只要spring.xml文件配置便可。sql
ApplicationContext應用上下文容器中獲取bean和從bean工廠容器中,獲取bean有什麼不一樣?
1.上下文獲取時:當咱們實例化xml時,該文件中配置的bean被實例化;
(前提是bean的配置是singleton,若是scope=prototype或者別的,也是延遲加載)
2.Bean工廠中獲取的時候:
BeanFactory factory = new XmlBeanFactory(
new ClassPathResource("applicationContext.xml"));
此時沒有實例化bean。
當factory.getBean()時,bean才被加載(延遲加載)。
通常是在移動設備中使用bean工廠方法,節省內存。
而大部分應用中,都是直接加載的。
獲取ApplicationContext對象引用的三種方法:
1.ClassPathXMLApplicationContext 經過類路徑
2.FileSystemXmlApplicationContext 經過文件路徑來獲取。
如("F:\JAVA INFORMATION\TARENA\xxxxx08\API")
不過記得要加轉義字符:("F:\\JAVA INFORMATION\\TARENA\\xxxxx08\\API")
3.XmlWebApplicationContext 下次再說。
Bean的生命週期(applicationContext方式):
任何技術的生命週期是重點:由於只有當生命週期弄明白了,才能駕馭這個技術。
1.實例化(當咱們的程序加載beans.xml文件),把咱們的bean(前提是singleton)
實例化到spring容器中(默認無參構造函數被調用)。
2.調用Set方法,設置屬性(必需要有一個set方法)。
3.若實現BeanNameAware接口,經過SetBeanName獲取配置的id號:如userService。
4.若實現BeanFactoryAware接口,SetBeanFactory傳遞beanFactory對象。
5.若實現ApplicationContextAware接口,setApplicaitonContext獲取上下文對象。
6.本身實現BeanPostProcessor接口,有before方法和after方法。
那麼,每個bean實例化以後,都會調用這個before和after
能夠實現「記錄每一個對象實例化的時機」&「過濾每一個調用對象ip的地址」等需求。
給全部對象添加一個屬性,或者函數。(ApplicationContext.xml文件配置bean)
(頗有面向切面編程的味道)針對全部對象編程。
7.若實現BeanInisizing接口,則在before方法後調用afterPropertySet方法。
8.若是本身在<bean init-method="init"></bean>,則能夠在bean定義本身的初始化方法。
9.使用bean
10.容器關閉
11.若是DisableBean接口,則實現destory()方法釋放資源。——>用的比較少。
12.可在bean中配置destory_method方法。
小結:在實際開發中,1-2-6-9-10數據庫
BeanFactory獲取bean對象,其bean的生命週期:
比前面的少了幾個,沒有ApplicationContextAware,BeanPostProcessor編程
__________
Bean裝載:
儘可能不要設置scope=‘prototype’,對性能影響較大。
1.固然也能夠在property中配置內部bean(用到較少)。
2.在bean的配置中,用一個parent,表示繼承。
3.Map,List,Set,集合的配置:
若是Collection c= new ArrayList();
那麼c只能有collection的方法,沒有ArrayList的方法。
但c是一個ArrayList的實例。
List是有序的,set是無序的。
List中能夠有相同的對象。set中不能有相同的對象,直接覆蓋掉了。
Map的循環能夠用entry(簡單):
或者Map的循環也能夠用迭代器。
Map的key相同的時候,也是覆蓋。
4.Properties的使用和注入:
<property>
<prop key="pp1">abcd</prop>
<prop key="pp2">44</prop>
</property>
property的循環也有兩個:一個是entry,一個是enumeration
5.設置空注值:<null/>包在property中。
自動裝配bean的屬性值:autowaire=五種(看文檔)
1.no:默認
2.byName:autowire=byName表示根據名字來自動裝載。
3.byType:顧名思義
4.constructor:
5.
特殊bean分散配置:
2.PropertyPlaceholderConfigurer:SpringProperties獲取配置的值。
也能夠引入<context:property-placeholder location="dev/db.properties"/>
${url}叫作佔位符**。
--------------AOP------------
Aspect Oriented Programming
面向切面(方面)編程:是對全部對象,或者一類對象進行編程。
-核心特色:在不增長代碼的基礎上,還增長新功能。
彙編語言:面向機器。僞機器指令 mov jump .
C語言:面向過程。最容易幫助人理解語言的本質。
系統語言,大部分都是用C語言寫的,如操做系統,數據庫,殺毒軟件,防火牆。
aOP面向切面編程:面向多個對象編程
如多個service都有事務,則抽取出來。另外還有日誌,安全。
aop在框架自己用的不少。
aop運行原理 + 案例:
1.aop的功能例如日誌,可經過公共方法,在每個須要的地方調用便可。
2.代理對象(spring提供proxyFactoryBean):經過代理接口來實現代理任務。
五種通知:
1.before(前置):實現MethodBeforeAdvice接口便可。
也是經過反射完成:當調用該代理方法時,便可知道參數等。
其中,applicationContext.xml須要配置
1.被代理的對象(目標對象)
2.前置通知(通知就是切面的實際實現)
3.代理對象(自己是ProxyFactoryBean對象實例)
3.1代理接口集
3.2織入通知
3.3配置被代理對象
<beans>
<!-- 1.配置被代理的對象 -->
<bean id="test1Service" class="com.Test1service">
<property name="name" value="wo"/>
</bean>
<!-- 2.配置前置通知,後置通知,環繞通知,異常通知,引入通知 -->
<bean id="myMethodBeforeAdvice" class="com.MyMethodBeforeAdvice">
<!-- 3.配置代理對象,它自己是ProxyFactoryBean對象實例 -->
<bean>
<!-- 3.1理接口集 -->
<property name="proxyInterfaces">
<list>
<value>com.jos.TestServiceInterface</value>
</list>
</property>
<!-- 3.2織入通知 -->
<property name="interceptorNames"> ----至關於調用setInterceptorNames()方法
<value>myMethodBeforeAdvice</value>
</property>
<!-- 3.3配置被代理對象 -->
<property name="target" ref="test1Service"/>
</bean>
</beans>
(一個類實現了多個接口,那麼這個接口之間是能夠互相轉的。)
2.3.4.5.後置通知,環繞通知,異常通知,引入通知。
SpringAOP中,經過代理對象去實現AOP技術的時候,獲取的ProxyFactoryBean是什麼類型?
答:返回的是一個動態代理對象。
1.若是實現了若干接口的話,Spring就使用(JDK)java.lang.reflct.Proxy代理
2.若是沒有實現接口的話,Spring就使用CGLIB庫生成目標對象。
對接口的代理,優於對類的代理,能夠實現更加鬆耦合的系統。
對類的代理,做爲備選。
不能對final方法進行通知。
SpringAOP還有另外了兩種實現方式:
1.一種方式是使用AspectJ提供的註解:
package test.mine.spring.bean;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class SleepHelper {
public SleepHelper(){
}
@Pointcut("execution(* *.sleep())")
public void sleeppoint(){}
@Before("sleeppoint()")
public void beforeSleep(){
System.out.println("睡覺前要脫衣服!");
}
@AfterReturning("sleeppoint()")
public void afterSleep(){
System.out.println("睡醒了要穿衣服!");
}
}
而後加上這個標籤:
<aop:aspectj-autoproxy/> 有了這個Spring就可以自動掃描被@Aspect標註的切面了
2.第三種,經常使用的。
<aop:config>頂級配置元素,相似於<beans>這種東西
<aop:pointcut>定義一個切點
<aop:advisor> 定義一個AOP通知者
MYSQL 和redis
1.一個是存在內存中,一個是磁盤。
2.SQL語句不一樣。
3.性能上,redis更適合存放熱點數據,好比用戶登陸信息及下單時用到的渠道、品種、合約信息。若是未命中緩存則去訪問mysql
4.redis有大量數據結構如string,list,set,hashSet等
Mybatis中:$
的like '%${ }%' 是用來作模糊查詢時候用。
Hibernate 與 Mybatis的區別
1.項目選擇上,若是一個項目基本沒有複雜查詢,那麼hibernate就很好用了。但若是複雜語句較多,Mybatis會更好。
2.工做量上,Mybatis須要手寫SQL以及resultmap,而hibernate有良好的映射機制,無需關心sql映射,能夠更專一於業務。
3.性能上,Hibernate會查詢全部字段,稍微有點消耗,Mybatis可針對須要來指定。
4.日誌,Hibernate有本身的日誌,Mybatis須要使用log4j
5.緩存……
SpringMVC中的註解:
1.@Controller
BeanFactory & FactoryBean 的區別: BeanFactory是用來管理bean的工廠。 FactoryBean是實現了FactoryBean<T>的bean。根據該bean的id從beanFactory中獲取的, 其實是factoryBean的getObject返回的對象。若是要獲取factorybean對象,能夠在id前 加上&符號來獲取。