-
AOP,面向切面編程,與垂直業(yè)務功能,實現(xiàn)程序功能的統(tǒng)一維護。
主要功能:日志記錄,性能統(tǒng)計,安全控制,事物處理,異常處理等等。(事務處理:任何操作數(shù)據(jù)庫的方法,尤其是增刪改,需要事物的處理,使用AOP時,執(zhí)行到某種類型的方法,或者某一層的類,自動開啟事務和獲取連接、提交事務、關閉事務的步驟,簡化了操作)
AOP實現(xiàn)方式:1、預編譯方式。(AspectJ) 2、運行期動態(tài)代理。(JDK動態(tài)代理、CGLib動態(tài)代理)(SpringAOP、JbossAOP)
切面的理解:例如系統(tǒng)中有產品管理、訂單管理、服務管理等等模塊(子功能),任一模塊(子功能),都需要記錄它的日志,控制它的事務,以及做一些安全驗證的功能。但是如果在每一個模塊(子功能)中去設計日志、事務、安全驗證,會帶來大量工作量,尤其當項目達到一定規(guī)模時,比如修改日志記錄的方式,那么則需要修改每一個模塊的日志功能,通過切面方式對開發(fā)人員是不可見的,當執(zhí)行任一模塊時,通過預編譯或者運行期動態(tài)代理方式,都會去記錄它的日志,實現(xiàn)了一處寫功能,處處可實現(xiàn)的方式,對于開發(fā)人員允許不知道有這樣功能的存在,這樣就簡化了操作(修改日志、編寫事物等),業(yè)務功能橫向走,切面垂直業(yè)務功能。
二、AOP基本概念(切面—>織入—>目標對象—>切入點—>連接點—>通知—>引入—>AOP代理:“切面”要執(zhí)行的動作,通過“織入”與所有功能模塊進行聯(lián)系,又通過“目標對象”找到具體功能模塊,通過“切入點”將要查找某個功能的某個方法,通過“連接點”找到該功能的特定方法的開始,通過“通知”將要執(zhí)行何種切面的動作,通過“引入”引入該動作用到的對象和方法,通過“AOP代理”實現(xiàn)該方法。)
AOP相關概念:
1、切面(Aspect):一個關注點(事務),這個關注點可能會橫切多個對象(產品管理、訂單管理)。
2、連接點(Joinpoint):程序執(zhí)行過程中的某個特定的點。(一個類中執(zhí)行的某個方法的開始)。
3、通知(Advice):在切面的某個特定的連接點上執(zhí)行的動作(方法執(zhí)行的時候,切面額外執(zhí)行的動作,比如說方法執(zhí)行時,開啟事物提交功能)。
4、切入點(Pointcut):匹配連接點的斷言,在AOP中通知和一個切入點表達式關聯(lián)(在切面中匹配一個具體的連接點(某個功能的方法的開始))。
5、引入(Introduction):在不修改類代碼的前提下,修改的是字節(jié)碼文件,為類添加新的方法和屬性。(類似于編譯期動態(tài)的修改class文件去增加新的屬性和方法,源代碼中并沒有這樣的屬性和方法),取決于使用AspectJ和SpringAOP的實現(xiàn)方式,使用方式不同,為類添加屬性和方法的方式是有區(qū)別的。
6、目標對象(Target Object):被一個或者多個切面所通知的對象。(例如存在一個訂單的service(對象)和一個商品的service(對象),執(zhí)行該模塊的功能時,切面會通知相對應的service,在執(zhí)行數(shù)據(jù)庫操作時,去加上事物的控制,這兩個service就是目標對象)。
7、AOP代理(AOP ?Proxy):AOP框架創(chuàng)建的對象,用來實現(xiàn)切面契約(aspect contract),包括通知方法執(zhí)行等功能(這里執(zhí)行的方法指的是切面里的執(zhí)行相應操作所用到的方法)開發(fā)時不知道這個對象存在的,也不清楚會創(chuàng)建成什么樣子。
8、織入(Weaving):把切面連接到其他的應用程序類型或者對象上,并創(chuàng)建一個被通知的對象,分為:編譯時織入、類加載時織入、執(zhí)行時織入。(使切面和對象(模塊功能)牽連起來)
Advice(通知)的類型(在切面某個特定連接點執(zhí)行的動作)
前置通知(Before advice):在某連接點(join point)(某個功能方法開始執(zhí)行前)之前執(zhí)行的通知,但不能阻止連接點前的執(zhí)行(除該方法外的其他方法的執(zhí)行)(除非它拋出一個異常)。
返回后通知(After returning advice):在某連接點(方法)正常完成后執(zhí)行的通知(將要執(zhí)行的切面功能)。
拋出異常后通知(After throwing advice):在方法拋出異常退出時執(zhí)行的通知(將要執(zhí)行切面的功能)。
后通知(After(finally)advice):當某連接點(方法)退出的時候執(zhí)行的通知(切面將要執(zhí)行的功能)(不論是正常返回還是異常退出都會執(zhí)行的通知)。
環(huán)繞通知(Around Advice):包圍一個連接點(join point)的通知(在整個方法的內部都有切面要執(zhí)行的功能存在,不分前后)。
Spring框架中AOP的用途:
用途1:提供了聲明式的企業(yè)服務(也可以是其他服務,例如互聯(lián)網服務),特別是EJB(重量級框架)的替代服務的聲明。
用途2:允許用戶定制自己的方面(切面),以完成OOP(面向對象編程,模擬世界中行為和方式,可以理解為實現(xiàn)一個功能的順序)與AOP(橫切的方式,可以理解為各個功能之間橫切的一種功能)的互補使用,可以實現(xiàn)自己橫切的功能。
三、Spring中的AOP(Spring中AOP的實現(xiàn)方式以及特點)
特點1:純java實現(xiàn),無需特殊的編譯過程(普通代碼需要加載才能執(zhí)行),不需要控制類加載器層次??梢愿玫倪M行控制(使用類加載器應當謹慎,容易方法生ClassNotFound異常這種情況)。
特點2:目前只支持方法執(zhí)行連接點(通知Spring Bean的方法執(zhí)行),(在執(zhí)行某方法時,才去執(zhí)行切面的功能)。
特點3:SpringAOP不是為了提供最完整的AOP實現(xiàn)(盡管它非常強大);而是側重于提供一種AOP實現(xiàn)和Spring IoC容器之間的整合,用于幫助解決企業(yè)應用中的常見問題。
特點4:SpringAOP不會與AspectJ(完整的、全面的AOP解決方案)競爭,也不會提供綜合全面的AOP解決方案。
有接口和無接口的SpringAOP實現(xiàn)區(qū)別:(一個類是否實現(xiàn)了某個接口,例如一個ProductService接口,一個ProductServiceImpl實現(xiàn)了該接口,在這類上切入的切面就是有接口的AOP)
SpringAOP對于有接口的使用標準的JavaSE動態(tài)代理作為AOP代理,這使得任何接口(或者接口集)都可以被代理。
SpringAOP對于沒有接口的實現(xiàn)類中使用CGLIB代理(如果一個業(yè)務對象并沒有實現(xiàn)一個接口)
四、Schema-based 實現(xiàn)AOP(基于配置文件實現(xiàn)AOP)
五、API實現(xiàn)AOP(基于API實現(xiàn)AOP)
六、AspectJ實現(xiàn)AOP
查看全部 -
@Resource和@Autowired都是做bean的注入時使用,其實@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要導入,但是Spring支持該注解的注入。
1、共同點
兩者都可以寫在字段和setter方法上。兩者如果都寫在字段上,那么就不需要再寫setter方法。
2、不同點
(1)@Autowired
@Autowired為Spring提供的注解,需要導入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
public?class?TestServiceImpl?{????//?下面兩種@Autowired只要使用一種即可????@Autowired????private?UserDao?userDao;?//?用于字段上???? ????@Autowired????public?void?setUserDao(UserDao?userDao)?{?//?用于屬性的方法上 ????????this.userDao?=?userDao; ????} }
@Autowired注解是按照類型(byType)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它的required屬性為false。如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier注解一起使用。如下:
public?class?TestServiceImpl?{ ????@Autowired ????@Qualifier("userDao")????private?UserDao?userDao;? }
(2)@Resource
@Resource默認按照ByName自動注入,由J2EE提供,需要導入包javax.annotation.Resource。@Resource有兩個重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以,如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不制定name也不制定type屬性,這時將通過反射機制使用byName自動注入策略。
public?class?TestServiceImpl?{????//?下面兩種@Resource只要使用一種即可 ????@Resource(name="userDao")????private?UserDao?userDao;?//?用于字段上???? ????@Resource(name="userDao")????public?void?setUserDao(UserDao?userDao)?{?//?用于屬性的setter方法上 ????????this.userDao?=?userDao; ????} }
注:最好是將@Resource放在setter方法上,因為這樣更符合面向對象的思想,通過set、get去操作屬性,而不是直接去操作屬性。
@Resource裝配順序:
①如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
②如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
③如果指定了type,則從上下文中找到類似匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
④如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配。
@Resource的作用相當于@Autowired,只不過@Autowired按照byType自動注入。
---一只noob
查看全部 -
@Bean:由SpringIoc容器配置和初始化對象,類似于XML配置文件的<bean/>,。(一般@Bean 需要在配置類中使用,即類上需要加上@Configuration注解)
查看全部 -
@Resource 適用于成員變量 一個參數(shù)的set方法,@Qualifier 使用于構造方法和多參數(shù)方法。
@qualifier:一般和@Autowired一起使用,有時候類型是接口的成員變量可能有多個實現(xiàn)類,按類型自動注入時可能會有多個Bean實例的情況,可以使用@Qualifier注解縮小范圍(或指定唯一),指定使用哪個接口的實現(xiàn)類來賦給當前的成員變量,也可用于指定單獨的構造器或方法參數(shù)。
查看全部 -
autowired注解數(shù)組和map
查看全部 -
autowired的參數(shù)required的說明。required默認值是false。
查看全部 -
Autowired注解可用于set方法、成員變量和構造函數(shù)。是常用的注解方法。autowired通過Type對bean進行注入的,而不是name。
查看全部 -
java的注解在jdk5之后引入。
Bean管理的注解實現(xiàn)及例子
1、Classpath掃描與組件管理
定義:從Spring3.0開始,Spring JavaConfig項目提供很多特性,包括通過注解定義Bean,而不是使用XML。
@Component:通用型注解,可用于任何Bean,可以注解任何類。
@Repository,@Service,@Controller是更有針對性的注解。(component的子注解)
@Repository:通常用于注解DAO層,即持久層。
@Service:通常用于注解Service層,即服務層。
@Controller:通常用于Controller層,即控制層(MVC).
查看全部 -
ResourceLoader 注入方式
查看全部 -
resourceloader例子
查看全部 -
resources
查看全部 -
自動裝配:無需在xml中指定property或是constructor-arg屬性。
byName:根據(jù)set中參數(shù)的bean id裝配bean實例。
byType:根據(jù)set中參數(shù)的bean類型裝配bean實例。
constructor:IOC容器查找有無構造器方法中的參數(shù)的類型
查看全部 -
定義:Spring中提供了一些以Aware結尾的接口,實現(xiàn)了Aware接口的Bean在被初始化后,可以獲取相應資源,通過Aware接口,可以對Spring相應資源進行操作(慎重),前提配置<bean>標簽,并使用ioc容器去記性加載。
ApplicationContextAware:Bean類實現(xiàn)該接口,通過覆蓋該接口提供的setApplicationContext方法,可以直接獲取spring上下文,而不用我們自己手動創(chuàng)建。
BeanNameAware:Bean類實現(xiàn)該接口,通過覆蓋該接口提供的setBeanName方法,可以得到bean的name(id)
同時實現(xiàn)兩個接口,通過setBeanName可以得到bean的name,通過applicationContext.getBean(this.name)得到此bean的實例。
查看全部 -
bean的生命周期包括以下四部分:定義、初始化、使用、銷毀。
bean的初始化(context啟動時加載Bean配置文件并生成Bean實例)包括兩種方式:實現(xiàn)org.springframework.beans.factory.InitializingBean接口,覆蓋afterPropertitesSet方法或者配置init-method。
bean使用:取出bean實例,調用其方法。
同樣bean的銷毀(銷毀bean容器創(chuàng)建的所有bean實例)也有兩種方式,實現(xiàn)org.springframework.beans.factory.DisposableBean覆蓋destory方法或配置destory-method。
或者配置全局的初始化、銷毀方法。
查看全部 -
Spring 注入是指在啟動Spring容器加載bean配置的時候完成對變量的賦值行為。注入方式分為:設值注入和構造注入。設值注入和構造注入則通過配置上的差異來區(qū)分。設值注入需要在調用類加set方法,構造注入是在調用類的構造方法傳參
查看全部
舉報