Q:依賴倒置原則(Dependency Inversion Principle,DIP),依賴注入(Dependency Injection,DI)和控制反轉(zhuǎn)(Inversion of Control,IoC)容器
依賴倒置原則(Dependency Inversion Principle, DIP)。這個(gè)設(shè)計(jì)準(zhǔn)則某種程度上和依賴注入模式有些關(guān)聯(lián)。DIP的出發(fā)點(diǎn)是:在應(yīng)用開發(fā)中,高層模塊不應(yīng)當(dāng)直接依賴低層模塊。DIP并不意味著依賴注入。這個(gè)準(zhǔn)則并沒有講到高層模塊如何知道調(diào)用哪個(gè)低層模塊。不過這一點(diǎn)通過實(shí)現(xiàn)工廠模式接口可以間接獲知,或者通過類似Spring框架、Pico容器、Guice或者Apache HiveMind之類的loC容器實(shí)現(xiàn)依賴注入從而得知高層模塊調(diào)用的具體哪個(gè)低層模塊。
依賴注入模式(Dependency Injection):在運(yùn)行時(shí)將類的依賴注入到代碼中。通過將依賴定義為接口,并將實(shí)現(xiàn)這個(gè)接口的實(shí)體類注入到主類的構(gòu)造器中來實(shí)現(xiàn)這個(gè)模式。這允許程序員在不同的實(shí)現(xiàn)之間轉(zhuǎn)換而不用去修改主類。依賴注入模式可以通過單一責(zé)任原則(Single Responsibility Principle)SRP來使得代碼高內(nèi)聚(high cohesion),因?yàn)樗蕾嚨耐ǔ6际峭瓿瑟?dú)立的功能的對象,例如,(通過DAO進(jìn)行)數(shù)據(jù)存取或(通過Service和Delegate類實(shí)現(xiàn))業(yè)務(wù)服務(wù)。
控制反轉(zhuǎn)容器(Inversion of Control Container,IoC),是一個(gè)支持依賴注入的容器。這種方式下,可以采用一個(gè)中心容器,例如Spring框架,Guice或者HiveMind,來定義哪個(gè)依賴應(yīng)該使用哪個(gè)實(shí)體類。Ioc的松耦合性可以帶來更多的靈活性,并且在程序運(yùn)行時(shí)更容易去切換到正確的依賴對象上。控制反轉(zhuǎn)模式的基本概念是,不去實(shí)際生成對象,而是去定義如何生成對象。不用直接在代碼中將模塊和服務(wù)硬編碼在一起,而是在配置文件中描述哪個(gè)模塊需要哪個(gè)服務(wù)。容器(例如Spring框架這個(gè)IoC容器)會負(fù)責(zé)將這兩者綁定起來。應(yīng)用IoC的時(shí)候,某對象所需的依賴會在創(chuàng)建的時(shí)候通過外部實(shí)體傳入,這些外部實(shí)體用來協(xié)調(diào)系統(tǒng)中的不同對象。也就是說,依賴是被注入到對象中去的。因此,IoC就是關(guān)于一個(gè)對象如何獲得其協(xié)作對象的引用的一種責(zé)任反轉(zhuǎn)機(jī)制。
DI和IoC的真正強(qiáng)大之處在于:
- 在運(yùn)行時(shí)而非編譯時(shí)綁定類間關(guān)系。例如,在Seam框架中,你可以對一個(gè)接口進(jìn)行兩種實(shí)現(xiàn):真正的實(shí)現(xiàn)和模擬(mock)的實(shí)現(xiàn),而在運(yùn)行時(shí)根據(jù)某個(gè)屬性、另一個(gè)文件存在與否或者某個(gè)優(yōu)先值去決定真正調(diào)用哪一個(gè)實(shí)現(xiàn)。這尤其當(dāng)你希望程序在不同場景下表現(xiàn)不同的行為時(shí),這是非常好用的。
- 使得代碼更容易進(jìn)行單元測試。
- 不用使用工廠或者單例模式就可以實(shí)現(xiàn)松耦合,其實(shí)現(xiàn)方法一致因此適合缺乏經(jīng)驗(yàn)的程序員。
Q:IoC中支持的依賴注入有哪些類型?
- 構(gòu)造子注入(例如,Spring框架):依賴是通過構(gòu)造器參數(shù)提供的。
- 設(shè)值方法注入(例如,Spring框架):依賴是通過JavaBeans屬性注入的(ex:setter方法)
- 接口注入(例如,Avalon):注入通過接口完成。
選擇哪種注入方式?
兩種依賴方式都可以使用,構(gòu)造器注入和Setter方法注入。最好的解決方案是用構(gòu)造器參數(shù)實(shí)現(xiàn)強(qiáng)制依賴,setter方法實(shí)現(xiàn)可選依賴。
Q:Bean的生命周期
BeanFactory中的Bean生命周期
- 在調(diào)用getBean方法之前,如果容器注冊了InstantiationAwareBeanPostProcessor接口,則在實(shí)例化bean之前調(diào)用postProcessBeforeInstantiation方法
- 根據(jù)配置情況調(diào)用Bean的構(gòu)造函數(shù)或者工廠方法實(shí)例化bean
- 如果容器注冊了InstantiationAwareBeanPostProcessor接口,則在實(shí)例化bean之前調(diào)用postProcessAfterInstantiation方法,對實(shí)例化后的bean進(jìn)行裝飾
- 如果Bean配置了屬性值,則在配置屬性值之前調(diào)用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法
- 調(diào)用Bean的屬性配置方法設(shè)置屬性值
- 如果Bean實(shí)現(xiàn)了BeanNameAware接口,則調(diào)用setBeanName方法,將配置文件中該Bean對應(yīng)的名稱設(shè)置到Bean中
- 如果Bean實(shí)現(xiàn)了BeanFactoryAware接口,則調(diào)用setBeanFactory方法,將BeanFactory實(shí)例傳到Bean中
- 如果容器注冊了BeanPostProcessor接口,則調(diào)用postProcessBeforeInitialzation(Object bean,String beanName)方法對Bean進(jìn)行加工操作,返回對象為加工后的Bean。BeanPostProcessor在Spring框架占有有重要地位,Spring提供的AOP以及動態(tài)代理均通過此接口完成。
- 如果Bean實(shí)現(xiàn)了InitializingBean接口,那么調(diào)用afterPropertiesSet方法
- 如果<bean>中通過init-method定義了初始化方法,則執(zhí)行此方法
- 如果容器注冊了BeanPostProcessor接口,則調(diào)用postProcessAfterInitialzation(Object bean,String beanName)方法,再次提供對Bean的加工機(jī)會
- 如果在<bean>中指定Bean的作用范圍為scope="prototype",將Bean返回給調(diào)用者,調(diào)用者負(fù)責(zé)Bean后續(xù)生命管理。如果scope="singleton",則將Bean放入Spring IoC容器的緩存池中,并將Bean引用返回給調(diào)用者,Spring繼續(xù)對Bean的后續(xù)生命周期進(jìn)行管理
- 對于scope="prototype"的Bean,當(dāng)容器關(guān)閉時(shí),將觸發(fā)Spring對Bean的后續(xù)生命管理工作,如果Bean實(shí)現(xiàn)了DisposableBean接口,則將調(diào)用afterPropertiesSet方法,可再次編寫釋放資源,記錄日志等操作
- 對于scope="prototype"的Bean,如果<bean>中通過destroy-method定義了銷毀方法,則執(zhí)行此方法
Bean的完整生命周期經(jīng)歷了各種方法調(diào)用,這些方法可以劃分為以下幾類:
- Bean自身的方法
這個(gè)包括了Bean本身調(diào)用的方法和通過配置文件中<bean>的init-method和destroy-method指定的方法 - Bean級生命周期接口方法
這個(gè)包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean這些接口的方法 - 容器級生命周期接口方法
這個(gè)包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個(gè)接口實(shí)現(xiàn),一般稱它們的實(shí)現(xiàn)類為“后處理器”。
Q:Bean的作用域
- singleton:這種bean范圍是默認(rèn)的,這種范圍確保不管接受到多少個(gè)請求,每個(gè)容器中只有一個(gè)bean的實(shí)例,單例的模式由bean factory自身來維護(hù)。
- prototype:原形范圍與單例范圍相反,為每一個(gè)bean請求提供一個(gè)實(shí)例。
- request:在請求bean范圍內(nèi)會每一個(gè)來自客戶端的網(wǎng)絡(luò)請求創(chuàng)建一個(gè)實(shí)例,在請求完成以后,bean會失效并被垃圾回收器回收。
- Session:與請求范圍類似,確保每個(gè)session中有一個(gè)bean的實(shí)例,在session過期后,bean會隨之失效。
- global-session:global-session和Portlet應(yīng)用相關(guān)。當(dāng)你的應(yīng)用部署在Portlet容器中工作時(shí),它包含很多portlet。如果你想要聲明讓所有的portlet共用全局的存儲變量的話,那么這全局變量需要存儲在global-session中。
Q:BeanFactory和ApplicationContext區(qū)別
ApplicationContext 的主要實(shí)現(xiàn)類是ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext,前者默認(rèn)從類路徑加載配置文件,后者默認(rèn)從文件系統(tǒng)中裝載配置文件。
- 利用MessageSource進(jìn)行國際化
- 事件發(fā)布機(jī)制
讓容器擁有發(fā)布應(yīng)用上下文事件的功能,包括容器啟動事件、關(guān)閉事件等。實(shí)現(xiàn)了 ApplicationListener 事件監(jiān)聽接口的Bean 可以接收到容器事件, 并對事件進(jìn)行響應(yīng)處理。在ApplicationContext 抽象實(shí)現(xiàn)類AbstractApplicationContext 中,我們可以發(fā)現(xiàn)存在一個(gè)ApplicationEventMulticaster,它負(fù)責(zé)保存所有監(jiān)聽器,以便在容器產(chǎn)生上下文事件時(shí)通知這些事件監(jiān)聽 者。 - 底層資源的訪問
ApplicationContext擴(kuò)展了ResourceLoader(資源加載器)接口,從而可以用來加載多個(gè)Resource,而BeanFactory是沒有擴(kuò)展ResourceLoader - LifeCircle
該接口提供start()和stop()方法用于控制異步訪問。在具體使用時(shí)該接口同時(shí)被ApplicationContext以及Bean實(shí)現(xiàn),ApplicationContext會將start/stop中的信息傳遞給容器中實(shí)現(xiàn)了該接口的Bean - BeanFactroy采用的是延遲加載形式來注入Bean的,即只有在使用到某個(gè)Bean時(shí)(調(diào)用getBean()),才對該Bean進(jìn)行加載實(shí)例化,這樣,我們就不能發(fā)現(xiàn)一些存在的Spring的配置問題。而ApplicationContext則相反,它是在容器啟動時(shí),一次性創(chuàng)建了所有的Bean。這樣,在容器啟動時(shí),我們就可以發(fā)現(xiàn)Spring中存在的配置錯(cuò)誤。
- BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor以及InstantiationAwareBeanPostProcessor 的使用,但兩者之間的區(qū)別是:BeanFactory需要手動注冊,而ApplicationContext則是自動注冊
Q:IoC容器內(nèi)部工作機(jī)制
Spring中的org.springframework.beans包和org.springframework.context包構(gòu)成了Spring框架IoC容器的基礎(chǔ)。
BeanFactory 接口提供了一個(gè)先進(jìn)的配置機(jī)制,使得任何類型的對象的配置成為可能。ApplicationContex接口對BeanFactory(是一個(gè)子接口)進(jìn)行了擴(kuò)展,在BeanFactory的基礎(chǔ)上添加了其他功能,比如與Spring的AOP更容易集成,也提供了處理[]message resource的機(jī)制(用于國際化)、事件傳播以及應(yīng)用層的特別配置,比如針對Web應(yīng)用的WebApplicationContext。
org.springframework.beans.factory.BeanFactory是Spring IoC容器的具體實(shí)現(xiàn),是Spring IoC 容器的核心接口,用來包裝和管理前面提到的各種bean。
- ResourceLoader從存儲介質(zhì)中加載Spring配置文件,并使用Resource表示這個(gè)配置文件的資源;
- BeanDefinitionReader讀取Resource所指向的配置文件資源,然后解析配置文件。配置文件中每一個(gè)<bean>解析成一個(gè)BeanDefinition對象,并保存到BeanDefinitionRegistry中;
- 容器掃描BeanDefinitionRegistry中的BeanDefinition,使用Java的反射機(jī)制自動識別出Bean工廠后處理器(實(shí)現(xiàn)BeanFactoryPostProcessor接口)的Bean,然后調(diào)用這些Bean工廠后處理器對BeanDefinitionRegistry中的BeanDefinition進(jìn)行加工處理。主要完成以下兩項(xiàng)工作:
(1)對使用到占位符的<bean>元素標(biāo)簽進(jìn)行解析,得到最終的配置值,這意味對一些半成品式的BeanDefinition對象進(jìn)行加工處理并得到成品的BeanDefinition對象;
(2)對BeanDefinitionRegistry中的BeanDefinition進(jìn)行掃描,通過Java反射機(jī)制找出所有屬性編輯器的Bean(實(shí)現(xiàn)java.beans.PropertyEditor接口的Bean),并自動將它們注冊到Spring容器的屬性編輯器注冊表中(PropertyEditorRegistry); - Spring容器從BeanDefinitionRegistry中取出加工后的BeanDefinition,并調(diào)用InstantiationStrategy著手進(jìn)行Bean實(shí)例化的工作;
- 在實(shí)例化Bean時(shí),Spring容器使用BeanWrapper對Bean進(jìn)行封裝,BeanWrapper提供了很多以Java反射機(jī)制操作Bean的方法,它將結(jié)合該Bean的BeanDefinition以及容器中屬性編輯器,完成Bean屬性的設(shè)置工作;
- 利用容器中注冊的Bean后處理器(實(shí)現(xiàn)BeanPostProcessor接口的Bean)對已經(jīng)完成屬性設(shè)置工作的Bean進(jìn)行后續(xù)加工,直接裝配出一個(gè)準(zhǔn)備就緒的Bean。
Q:請舉例說明如何在Spring中注入一個(gè)Java Collection?
Spring提供了以下四種集合類的配置元素:
- <list> : 該標(biāo)簽用來裝配可重復(fù)的list值
- <set> : 該標(biāo)簽用來裝配沒有重復(fù)的set值
- <map>: 該標(biāo)簽可用來注入鍵和值可以為任何類型的鍵值對
- <props> : 該標(biāo)簽支持注入鍵和值都是字符串類型的鍵值對
<beans>
<!-- Definition for javaCollection -->
<bean id="javaCollection" class="com.howtodoinjava.JavaCollection">
<!-- java.util.List -->
<property name="customList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</list>
</property>
<!-- java.util.Set -->
<property name="customSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</set>
</property>
<!-- java.util.Map -->
<property name="customMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="UK"/>
</map>
</property>
<!-- java.util.Properties -->
<property name="customProperies">
<props>
<prop key="admin">admin@nospam.com</prop>
<prop key="support">support@nospam.com</prop>
</props>
</property>
</bean>
</beans>
Q:Spring Bean的自動裝配
在Spring框架中,在配置文件中設(shè)定bean的依賴關(guān)系是一個(gè)很好的機(jī)制,Spring容器還可以自動裝配合作關(guān)系bean之間的關(guān)聯(lián)關(guān)系。這意味著Spring可以通過向Bean Factory中注入的方式自動搞定bean之間的依賴關(guān)系。自動裝配可以設(shè)置在每個(gè)bean上,也可以設(shè)定在特定的bean上。
下面的XML配置文件表明了如何根據(jù)名稱將一個(gè)bean設(shè)置為自動裝配:
<bean id="employeeDAO" class="com.howtodoinjava.EmployeeDAOImpl" autowire="byName" />
除了bean配置文件中提供的自動裝配模式,還可以使用@Autowired注解來自動裝配指定的bean。在使用@Autowired注解之前需要在按照如下的配置方式在Spring配置文件進(jìn)行配置才可以使用。
<context:annotation-config />
也可以通過在配置文件中配置AutowiredAnnotationBeanPostProcessor 達(dá)到相同的效果。
<bean class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
配置好以后就可以使用@Autowired來標(biāo)注了。
自動裝配局限性
- 重寫: 你仍需用 <constructor-arg>和 <property> 配置來定義依賴,意味著總要重寫自動裝配。
- 基本數(shù)據(jù)類型:你不能自動裝配簡單的屬性,如基本數(shù)據(jù)類型,String字符串,和類。
- 模糊特性:自動裝配不如顯式裝配精確,如果有可能,建議使用顯式裝配。
Q:Spring三種配置方式
1 基于XML配置的方式配置Spring
在Spring框架中,依賴和服務(wù)需要在專門的配置文件來實(shí)現(xiàn),我常用的XML格式的配置文件。這些配置文件的格式通常用<beans>開頭,然后一系列的bean定義和專門的應(yīng)用配置選項(xiàng)組成。
SpringXML配置的主要目的時(shí)候是使所有的Spring組件都可以用xml文件的形式來進(jìn)行配置。這意味著不會出現(xiàn)其他的Spring配置類型(比如聲明的方式或基于Java Class的配置方式)
Spring的XML配置方式是使用被Spring命名空間的所支持的一系列的XML標(biāo)簽來實(shí)現(xiàn)的。Spring有以下主要的命名空間:context、beans、jdbc、tx、aop、mvc和aso。
<beans>
<!-- JSON Support -->
<bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"/>
</beans>
下面這個(gè)web.xml僅僅配置了DispatcherServlet,這件最簡單的配置便能滿足應(yīng)用程序配置運(yùn)行時(shí)組件的需求。
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2 基于Java配置的方式配置Spring
Spring對Java配置的支持是由@Configuration注解和@Bean注解來實(shí)現(xiàn)的。由@Bean注解的方法將會實(shí)例化、配置和初始化一個(gè)新對象,這個(gè)對象將由Spring的IoC容器來管理。@Bean聲明所起到的作用與<bean/> 元素類似。被@Configuration所注解的類則表示這個(gè)類的主要目的是作為bean定義的資源。被@Configuration聲明的類可以通過在同一個(gè)類的內(nèi)部調(diào)用@bean方法來設(shè)置嵌入bean的依賴關(guān)系。
最簡單的@Configuration 聲明類請參考下面的代碼:
@Configuration
public class AppConfig
{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
對于上面的@Beans配置文件相同的XML配置文件如下:
<beans>
<bean id="myService" class="com.howtodoinjava.services.MyServiceImpl"/>
</beans>
上述配置方式的實(shí)例化方式如下:利用AnnotationConfigApplicationContext 類進(jìn)行實(shí)例化
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
要使用組件組建掃描,僅需用@Configuration進(jìn)行注解即可:
@Configuration
@ComponentScan(basePackages = "com.howtodoinjava")
public class AppConfig {
...
}
在上面的例子中,com.acme包首先會被掃到,然后再容器內(nèi)查找被@Component 聲明的類,找到后將這些類按照Sring bean定義進(jìn)行注冊。
如果你要在你的web應(yīng)用開發(fā)中選用上述的配置的方式的話,需要用AnnotationConfigWebApplicationContext 類來讀取配置文件,可以用來配置Spring的Servlet監(jiān)聽器ContrextLoaderListener或者Spring MVC的DispatcherServlet。
<web-app>
<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified @Configuration classes. Fully-qualified packages may also be
specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.AppConfig</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.web.MvcConfig</param-value>
</init-param>
</servlet>
<!-- map all requests for /app/* to the dispatcher servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
3 用注解的方式配置Spring
Spring在2.5版本以后開始支持用注解的方式來配置依賴注入。可以用注解的方式來替代XML方式的bean描述,可以將bean描述轉(zhuǎn)移到組件類的內(nèi)部,只需要在相關(guān)類上、方法上或者字段聲明上使用注解即可。注解注入將會被容器在XML注入之前被處理,所以后者會覆蓋掉前者對于同一個(gè)屬性的處理結(jié)果。
注解裝配在Spring中是默認(rèn)關(guān)閉的。所以需要在Spring文件中配置一下才能使用基于注解的裝配模式。如果你想要在你的應(yīng)用程序中使用關(guān)于注解的方法的話,請參考如下的配置。
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
在 <context:annotation-config/>標(biāo)簽配置完成以后,就可以用注解的方式在Spring中向?qū)傩浴⒎椒ê蜆?gòu)造方法中自動裝配變量。
下面是幾種比較重要的注解類型:
@Required:該注解應(yīng)用于設(shè)值方法。
@Autowired:該注解應(yīng)用于有值設(shè)值方法、非設(shè)值方法、構(gòu)造方法和變量。
@Qualifier:該注解和@Autowired注解搭配使用,用于消除特定bean自動裝配的歧義。
JSR-250 Annotations:Spring支持基于JSR-250 注解的以下注解,@Resource、@PostConstruct 和 @PreDestroy。
Q:Spring中AOP相關(guān)基礎(chǔ)問題
解釋AOP:
面向切面的編程,或AOP, 是一種編程技術(shù),允許程序模塊化橫向切割關(guān)注點(diǎn),或橫切典型的責(zé)任劃分,如日志和事務(wù)管理。Aspect 切面:
AOP核心就是切面,它將多個(gè)類的通用行為封裝成可重用的模塊,該模塊含有一組API提供橫切功能。比如,一個(gè)日志模塊可以被稱作日志的AOP切面。根據(jù)需求的不同,一個(gè)應(yīng)用程序可以有若干切面。在Spring AOP中,切面通過帶有@Aspect注解的類實(shí)現(xiàn)。關(guān)注點(diǎn)和橫切關(guān)注的區(qū)別
關(guān)注點(diǎn)是應(yīng)用中一個(gè)模塊的行為,一個(gè)關(guān)注點(diǎn)可能會被定義成一個(gè)我們想實(shí)現(xiàn)的一個(gè)功能。
橫切關(guān)注點(diǎn)是一個(gè)關(guān)注點(diǎn),此關(guān)注點(diǎn)是整個(gè)應(yīng)用都會使用的功能,并影響整個(gè)應(yīng)用,比如日志,安全和數(shù)據(jù)傳輸,幾乎應(yīng)用的每個(gè)模塊都需要的功能。因此這些都屬于橫切關(guān)注點(diǎn)。連接點(diǎn)
連接點(diǎn)代表一個(gè)應(yīng)用程序的某個(gè)位置,在這個(gè)位置我們可以插入一個(gè)AOP切面,它實(shí)際上是個(gè)應(yīng)用程序執(zhí)行Spring AOP的位置。