業務邏輯需要多個對象合作來實現,這樣多個對象之間就存在依賴關系。控制反轉把應用從復雜的對象依賴關系中解放出來,將依賴關系交給IoC容器管理(具體地就是將新建對象、為對象引用賦值等操作交給容器完成)。
1.2 IoC容器設計與實現:BeanFactory與ApplicationContext
1.實現BeanFactory的簡單容器系列--實現了容器的最基本功能。
2.ApplicationContext應用上下文,在1的基礎上,增加了許多面向框架的特性以及對應用環境的適配。
3.BeanDefinition抽象了對Bean的定義,用於管理對象和對象之間的依賴關系,是容器實現依賴反轉的核心數據結構。
1.2.1 容器的設計

1.BeanFactory接口
2.BeanFactory設計原理(以XmlBeanFactory為例)
DefaultListableBeanFactory是默認的完整容器功能實現類,XMLBeanFactory繼承該類並添加讀取XML配置文件的功能。

編程式使用:

3.ApplicationContext
面向框架的使用風格
4.ApplicatioinContext設計原理(以FileSystemXmlApplicationContext為例)
1.2.3 IoC容器初始化過程(以FileSystemXmlApplicationContext為例)
IoC容器的初始化包括 BeanDefinition的定義、載入和注冊三個過程(即1.2.1.2種函數式使用IoC),被封裝在refresh()方法中。
-
Resource定位:定位BeanDefinition資源的位置。
-
BeanDefinition的載入:把上一步定位的資源載入,並轉變為IoC容器內部的數據結構,即BeanDefinition(POJO對象在IoC容器中的抽象)。
-
向IoC容器注冊這些BeanDefinition(到一個HashMap),具體是調用BeanDefinitionRegistry接口。
注意:這個過程並不包括依賴注入;依賴注入一般發生在第一次調用getBean時,但可以通過Bean的lazyinit屬性調控。
下面具體講這三個過程。
1.3 IoC詳細初始化過程
1.3.1 BeaDefinition的Resource定位

在FileSystemXmlApplicationContext的構造函數中,refresh()啟動容器初始化。
refresh(){
refreshBeanFactory(){
1.關閉可能存在的BeanFactory
2.createBeanFactory(){}
3.loadBeanDefinitions(BeanFacotory){
//定位BeanDefinition的兩種方式
1.ResourcePatternResolver.getResource()
2.getResource(){
1.CLASSPATH: new ClassPathResource()
2.URL: getResourceByPath()
}
}
//載入
3.Reader(BeanFactory);
//交給具體的reader,載入BeanDefinitions。
//配置reader
4.loadBeanDefinitions(Reader){
1.getConfigResources();//返回Resources【】或者String[]
2.reader.loadBeanDefinitions( Resources[]){
1.reader.loadBeanDefinition( Resources[i]){
1. loadBeanDefinitions( EncodedResource(resource)){
//創建InputSource並設置字符集
1.InputSource inputsource = new inputSource(
encodeResource.getResource().getInputStream()
).setEncoding(encodeResource.getEncoding());
//真正載入
2.doLoadBeanDefinitions( inputsource,encodeResource.getResource){
//加載前的准備工作
//交給DocumentReader去讀取
1.registerBeanDefinitions(doc, resource){
1.documentReader = createBeanDefinitionDocumentReader();
//先完成通用xml解析,再按照Bean規則解析。
2.documentReader.registerBeanDefinitoins(doc, createContext(resource)){
//真正加載、解析
doRegisterBeanDefinitoins(Element root){
parseBeanDefinitions(){
//默認標簽
1.parseDefaultElement(){
//包含了對beans、bean、alias、import標簽的解析,以bean為例子
processBeanDefinition(){
//解析
parseBeanDefinitionElement(){};
//注冊
registerBeanDefinition(){};
//通知相關監聽器
fireComponentRegistered();
};
};
//自定義標簽
2.parseCustomElemtn();
};
};
};
};
};
};
}
}; } // } }}/* 1.refresh 2.refreshBeanFactory 2.1 關閉可能存在的BeanFactory 2.1 createBeanFactory(){} 3.loadBeanDefinitions(BeanFacotory) 3.1定位BeanDefinition的兩種方式 //載入 3.2 Reader(BeanFactory);//關聯reader和beanFactory 4.loadBeanDefinitions(Reader) 4.1 獲取資源 5.reader.loadBeanDefinitions( Resources[]) 5.1 設置字符集 5.2 取得XML的inputSource 6.doLoadBeanDefinitions( inputsource,encodeResource.getResource) 6.1 解析XML-->document 7.registerBeanDefinitions(doc, resource) 7.1 創建DocumentReader 8. documentReader.registerBeanDefinitoins() 9. doRegisterBeanDefinitoins(Element root) 10. parseBeanDefinitions(){ //真正解析,針對不同標簽解析、注冊、通知監聽器 //默認標簽 1.parseDefaultElement(){ //包含了對beans、bean、alias、import標簽的解析,以bean為例子 processBeanDefinition(){ //解析 parseBeanDefinitionElement(){}; //注冊 registerBeanDefinition(){}; //通知相關監聽器 fireComponentRegistered(); }; }; //自定義標簽 2.parseCustomElemtn();} */
1.3.2 BeanDefinition的載入和解析
把定義的BeanDefinition轉為IoC容器內部數據結構(HashMap)。

可以看到調用是從最上層的AbstractApplicaitonContext一步步往繼承樹子節點走。
-
refresh()//AbstractApplicaitonContext
-
refreshBeanFactory(){ //AbstractRefreshableApplicationContext
createBeanFactory-->DefaultListableBeanFactory
loadBeanDefinitions-->具體的實現的Reader
}
//處理默認標簽--parseDefaultElemnt()包含 import,beans,bean,alias標簽,下面只是bean標簽
processBeanDefinition(Element ele, BeanDefinitionParseDelegate delegate){
1.delegate.parseBeanDefinitionElement(Elemnt , BeanDefinition ){
1.1提取id和name,解析beanName,parseBeanDefinitionElement(Element, BeanName, BeanDefinition){
1.1.1 提取class和parent,創建GenericBeanBeanDefinition(className, parent);
1.1.2 解析bean屬性
1.1.3 解析bean的子元素屬性,包括:Meta,LookupOverrideSubElement,ReplaceMethodsSubElement
ConstructorArgElements,PropertyElements,QualifierElements
};
return BeanDefinitionHolder(BeanDefinition, beanName, aliasesArray);
};
//解析默認標簽中的自定義標簽
2.delegate.decorateBeanDefinitionIfRequired();
//注冊
3.BeanDefinitionReaderUtils.registerBeanDefinition(BeanDefinitionHolder , BeanDefinitionRegistry{
3.1 使用beanName做唯一注冊標識
registry.registerBeanDenifition(beanName, BeanDefinition);
3.2 注冊所有別名
registry.registerBeanDenifition(beanName, alias);
};
4.getReaderContext().fireComponentRegistered(); //為擴展保留
}
//處理默認標簽--parseDefaultElemnt()包含 import,beans,bean,alias標簽,下面只是alias標簽
processAliasRegisteration(){
1.提取BeanName和alias,都不可空,否則拋出異常
2.getReaderContext().getRegistery().registerAlias(name, alias); }
//處理默認標簽--parseDefaultElemnt()包含 import,beans,bean,alias標簽,下面只是import標簽
嵌入式Beans,遞歸解析beans。
-
parseBeanDefinitionElement() //解析
BeanDefinition只是一些靜態配置信息,需要完成數據向容器的注冊,才能完全發揮容器的作用。
1.3.3 BeanDefinition在容器的注冊
1.private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
將BeanName作為鍵, BeanDefinition作為值保存。
2.

1.4 依賴注入(Bean的加載)
<u>依賴注入是用戶第一次向容器申請Bean時觸發(例外:lazy-init,可以控制Bean的預實例化)。</u>

FactoryBean
一般Spring利用反射機制通過bean的class屬性實現bean。這樣比較復雜,在<bean>配置大量信息。可以通過實現FactoryBean接口,在getObject方法中來定制實例化bean的邏輯。另外,該FactoryBean的getBean方法返回的不是FactoryBean(“&beanname”這樣取得)而是getObejct方法的bean。
1.4.1 實例化過程
getBean(){
doGetBean(){
1.//提取beanName
2.嘗試從緩存或者實例工廠獲取bean,取得的bean是原始狀態,還需要getObjectForBeanInstance
getSingleton(beanName, true//允許早期依賴);
3. 緩存沒有,則新創建。
3.1 原型模式的循環依賴檢測
3.2 當XML中沒有bean的配置時,去parentBeanFactory尋找
3.3 取得BeanDefinition后,轉為RootBeanDefinition
3.4 存在依賴Bean,遞歸調用
3.5 根據Scope創建bean
每種scope,實際都是以下方法:
3.5.1 createBean();
3.5.2 getObjectForBeanInstance();
};
};
1、緩存中獲取
getSingleton(beanName, true//允許早期依賴);
1.檢測singletonObjects();獲得bean則返回// map存放beanName和beanInstance
2.上一步沒有獲得bean,檢測earlySingletonObjects();獲得bean則返回//map存放還在創建過程中的bean,循環檢測
3.前兩步都沒有獲得bean,且允許早期依賴,從singletonFactories中獲取ObjectFactory初始化策略,初始化bean
4.取得bean,
調用getObjectForBeanInstance{
1.檢測是否是FactoryBean,
2.否直接返回bean,
3.是調用getObjectFromFacrotyBean(beanName){
1.檢測單例
2.doGetObjectFromFacrotyBean(){
1.檢測權限
2.factory.getObject();
//ObjectFactoryBean的后處理器--AbstractAutowireCapableBeanFactory
3.postProcessObjectFromFactoryBean();
//盡可能保證在Bean初始化后,都會調用注冊的BeanPostProcessor的postProcessAfterInitialization方法
};
};
4.返回getObject方法的結果。
}
若這三步都沒有獲得,則需要新建。
2、獲取單例(創建緩存中不存在的單例)
getSingleton(beanName, singletonFactory){
在singletonObjects上加鎖
1.緩存檢測,/*構造器循環依賴無法解決。setter循環依賴通過,提取暴露一個工廠方法,並將在當前創建bean池該bean的標識符,提供還未創建完成的Bean。
*/
2.beforeSingletonCreaton();//記錄正在創建的狀態
3.singletonFactory.getObject(){
1.createBean(beanName, mbd, args){
};
4.afterSingleCreation(); //刪除正在創建的狀態
5.addSingleton(beanName, singletonObject);//創建好的bean加入緩存,並刪除各種輔助狀態
}
createBean(beanName, mbd, args){
解析class
1.mbd.prepareMethodOverrides();//驗證並准備覆蓋的方法,主要是lookup-method和replace-method屬性。
2.Object bean = resolveBeforeInstantiation(beanName, mbd){//對Bean的屬性做些前置處理
bean = applyBeanPostProcessorsBeforeInstantiation(){
bean=applyBeanPostProcessorBeforeInstantiation();
if(bean!=null) applyBeanPostProcessorAfterInstantiation();
};//實例化前后處理器應用
if(bean!=null)
applyBeanPostProcessorsAfterInitialization();//實例化后后處理器應用,滿足spring規則。
};
3.if(bean!=null) return bean;//短路測試
4.doCreateBean(beanName, mbd, args){
1.清除緩存?
2.createBeanInstance(){
1.resolveBeanClass //解析class
2.非public類無法訪問,所以無法構建bean
3.mbd中工廠方法不為空,調工廠創建。
instantiateUsingFactoryMethod();
4.解析構造函數並實例化,緩存在resolvedConstructorOrFactory中。
5. autowireConstructor(){
//太復雜,大致為
確定參數(傳入了參數(用戶調用getBean可以傳入),緩存中參數,配置文件中參數)
確定構造函數
轉換參數類型和構造函數不確定性驗證--不太懂
根據實例化策略(instantiate)和構造函數和參數,實例化Bean
};//構造函數自動注入
instantiateBean();//默認構造函數,沒有參數直接根據實例化策略實例化Bean
instantiate{//實例化策略
if(beanDefinition.getMethodOverrides().isEmpty()) 直接反射
else 動態代理將覆蓋的方法織入
}
}; Bean的合並后處理
3.依賴處理 addsingletonFactory() //單例,可循環依賴,當前Bean正在創建中,曝光工廠方法
4.populateBean(){//屬性注入
1.getPropertyValues//提取屬性
2.根據BeanWraper和pvs是否為空,考慮注入
3. //提取依賴的Bean,放入PropertyValues中。
autoWiredByName();
autoWiredByType();//比較復雜,暫不了解
4.postProcessPropertyValues();//填充屬性前對屬性再次處理。
5.applyPropertyValues();//應用屬性到Bean中。 }; 5.initializeBean(){//Bean配置里面的init-method屬性。前面已經執行了Bean的實例化和屬性填充,現在是調用 //用戶的初始化方法 1.invokeAwareMethods(){ 判斷是BeanNameAware、BeanClassAware、還是BeanFactoryAware,分別傳入相應的Aware前面部分。 //實現Aware的接口會取得一些資源 }; 2.applyBeanPostProcessorsBeforeInitialization(){ postProcessBeforeInitialization(); }; 3.invokeInitMethods(){ 先執行自定義Bean的initializingBean接口中afterPropertiesSet, 然后是init-method方法。 }; 4.applyBeanPostProcessorsAfterInitialization(){ postProcessAfterInitialization(); }; }; 6.循環依賴檢測與處理 7.registerDisposableBeanIfNecessary(){ registerDispoableBean();//屬性配置destrot-method //自定義的bean銷毀方法 registerDestructionCallback(); }//注冊DisposableBean銷毀方法並返回 };};
1.5 ApplicatonContext
1.5.1 設置配置文件路徑
setConfigoLcations(String[] locations){
resolcePath();//解析路徑
}
1.5.2 擴展功能
refresh(){
1.prepareRefresh();
2.beanFactory=obtainFreshBeanFactory();
3.prepareBeanFactory(beanFactory);
4.postProcessBeanFactory(beanFactory);
5.invokeBeanFactoryPostProcessors(beanFactory);
6.registerBeanPostProcessors(beanFactory);
7.initMessageSource();
8.initApplicationEventMulticaster();
9.onRefresh();
10.registerListeners();
11.finishBeanFactoryInitializatioin(beanFactory);
12.finishRefresh();
}
1.prepareRefresh(); 准備刷新上下文環境
prepareRefresh(){
initPropertySources();//留給子類覆蓋,個性化地屬性處理和設置
getEnviroment().validateRequiredProperties();
};
2.beanFactory=obtainFreshBeanFactory();初始化BeanFactory並進行XML文件的讀取
beanFactory=obtainFreshBeanFactory(){
refreshBeanFactry(){
1.關閉已有Beanfacory
2.createBeanFactory();
3.customizeBeanFactory(){
//開始擴展基本的bean
覆蓋,循環依賴,
//注解方式注入的支持
setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidatResolver());
};//定制BeanFactory
4.loadBeanDefinitions(beanFactory);
5.保存至全局beanFactory
};
};
3.prepareBeanFactory(beanFactory);對beanFactory功能填充.ApplicationContext
prepareBeanFactory(beanFactory){
//添加表達式語言處理器
setBeanExpressionResolver(new StandardBeanExpressionResolver()){
}; -->在屬性填充解析屬性值時,調用evaluateBeanDefinitionString(){
this.beanExpressionResolver.evaluate();
}
//添加屬性編輯器-->一些屬性的是自定義的類,spring無法識別
addPropertyEditorRegistrar();
//添加BeanPostProcessor
addBeanPostProcessor(new ApplicationContextAwareProcessor(...)){
該處理器會調用 postprocessBefore||AfterInitialization()
invokeAwareInterfaces(){
獲取一些資源
};
};
//設置忽略自動裝配的接口-->在invokeAwareInterfaces中的資源的獲取是由應用獲取的,也就是說這些資源的依賴關系已經不再是容器管理。所以需要忽略。
//設置幾個自動裝配的特殊規則-->注冊依賴
//添加AspectJ的支持
//添加默認系統環境的bean
};
4.postProcessBeanFactory(beanFactory);子類覆蓋方法額外處理
通過實現BeanFactoryPostFactory接口,BeanFactory會在實例化任何bean之前獲得配置信息,從而能夠正確解析bean描述文件的變量引用。
5.invokeBeanFactoryPostProcessors(beanFactory);激活各種BeanFactory處理器
6.registerBeanPostProcessors(beanFactory);注冊攔截Bean創建的Bean處理器。在bean實例化時調用。
//BeanFactory沒有實現后處理器的自動注冊,Application實現自動注冊
registerBeanPostProcessors(beanFactory){
};
7.initMessageSource();為上下文初始化Message源
8.initApplicationEventMulticaster();初始化應用消息廣播器,放入applicationEventMulticaster中
1.定義事件繼承ApplicationEvent
2.定義監聽器ApplicationListener
3.定義事件廣播器
initApplicationEventMulticaster(){
注冊事件廣播器
}
4.事件廣播器有下面方法
當spring產生事件時,會調用下面方法遍歷監聽器
public void multicastEvent(final ApplicationEvent event){
listener.onApplicationEvent(event);//每個監聽器都會獲取到事件,但是否處理,則是監聽器內部邏輯
}
9.onRefresh();initialize other special beans in specific context subclasses
10.registerListeners();查找Listener bean,注冊到消息廣播器中。
registerListeners(){
//硬編碼方式
for(Application<?> listener : getApplicationListeners()){
getApplicationEventMulticaster().addApplicationListener(listener);
}
//配置文件注冊監聽器
String[] litenerBeanNames = getBeanNmesForType(ApplicationListener.class,true,false);
for(String lisName:listenerBeanNames){
getApplicationEventMulticaster().addApplicationListeer(lisName);
}
}
11.finishBeanFactoryInitializatioin(beanFactory);初始化剩下的單實例(非惰性)
finishBeanFactoryInitializatioin(beanFactory){
1.ConversionService的設置
注冊在配置文件中的轉換器,conversionServic,該 Bean中包含轉換器,用於類型轉換。
Converter<?class, ?class>比如前面的Converter<String, Date>//轉換器
2.凍結所有bean的定義,再不能被修改或者進一步處理。
freezeConfiguration();
3.ApplicationContext會在啟動時將所有單例bean提前實例化,便於在啟動過程中發現配置中的錯誤,而不是在調用bean時才發現。
preInstantiateSingletons(){}
};
12.finishRefresh();完成刷新,通知生命周期處理器lifecycleProcessor,發出ContextRefreshEvent通知別人
//spring提供LifeCycle接口,包含start/stop接口。分別在啟動和關閉時調用。
finishRefresh(){
initLifecycleProcessor();
gtLifecycleProcessor().onfresh();//啟動所有實現lifecyce的bean。
//啟動完成后通過事件發布機制發布事件
publishEvent(new ContextRefreshedEvent(this));
};
1.6 AOP
1.6.1 AopNamespaceHandler--AspectJ的解析器
public void init(){
registerBeanDefinitionParser("aspect-autoprxy",new AspectJAutoProxyBeanDefinitionParser(){
public BeabDefinition parse(Element, ParseContext){
//注冊AnnotationAwareAspectJAutoProxyCreator
registerAspectJAnnotationAutoProxyCreatorIfNecessary(Element, ParseContext){
1.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(),
parserContext.extractSource(sourceElement)
){//自動注冊AnnotationAwareAspectJAutoProxyCreator(該類實現Aop功能)
return registerOrEscalateApcRequired(
AnnotationAwareAspectJAutoProxyCreator.calss,...){
//存在自動代理創建器,且與現在的不一致,需要根據優先級判斷。
在register中注冊代表自動創建器bean
return beandefinition;
};
};
//處理proxy-target-calss(true表示強制使用CGLIB動態代理)和expos-proxy屬性
2.useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement());
//注冊組件並通知。
3.registerComponentIfNecessary(beanDefinition, parserContext);
};
}
});
}
1.6.2 創建AOP代理
AnnotationAwareAspectJAutoProxyCreator繼承自AbstracAutoProxyCreator,有方法postProcessorAfterInitializatioin()
postProcessorAfterInitializatioin(){
//封裝指定bean
wrapIfNecessary(bean, beanName, cacheKey){
1.各種直接返回場景,已處理、無需增強..
2.獲取增強
Object[] specificInterceptors = getAdviceAndAdvisorsForBean(bean.class, beanName, null){
findEligibleAdvisors(beanClss, beanName){
2.1 findCandidateAdvisors(){};
2.2 findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
return eligibleAdisors;
};
};
3.如果有增強,則針對增強創建代理
createProxy(bean,getClass(),beanName, specificInterceptors, new SingletoTargetSource(bean));
};
}
2.
2.1 提取advisors
findCandidateAdvisors(){
//將通過配置文件配置的AOP加載進來
List<Advisor> advisors = super.findandidateAdvisors();
2.1.1 advisors.addAll(this.aspectJAvdivsorsBuilder.buildAspectJAdvosprs());
return advisors;
};
2.1.1
buildAspectJAdvispos(){
1.通過BeanFactoryUtils獲取所有beanNames,
2.遍歷beanNames,進而獲取beanType
3.如果beanType上有Aspect注解
解析注解中的增強方法
advisorFactory.getAdvisors(factory){
};
4.advisors.addAll();//記錄在緩存中並返回advisors
}
2.1.1.3
getAdvisors(factory){
//普通增強器的獲取,包括切點注解的獲取和根據注解信息生成增強
1.getAdvisor(...){
//獲取切點注解
getPointcut(...){
//獲取方法上的注解
aspectJAnnotation=findAspectJAnnotationOnMethod(...){
1.設置注解敏感類
2.遍歷敏感類與傳入的方法上的標注匹配,來確定是哪個注解
findAnnotation(method, class){}
};
//創建用於封裝獲取的信息的AspectJExpressionPointcut實例
ajexp=new AspectJExpressionPointcut(...);
//提取得到的注解中的表達式
ajexp.setExpression(aspectJannotation.getPointcutExpression());
return ajexp;
};
//根據獲取的切點信息生成增強器
return new InstantiationModelAwarePointcutAdvisorImpl(...){
1.簡單地將獲取的信息封裝在InstantiationModelAwarePointcutAdvisorImpl實例中
2.
//初始化對應的增強器
instantiateAvice(){
return ...getAdvice(...){
1.一些判斷邏輯
//根據不同的注解類型封裝不同的增強器
2.switch(aspectJAnnotation.getAnnotationType()){
case AtBefore.... case AtAfter... case AtAfterReturning .... } } }; }; } 2.加入同步實例化增強器 //用於引介增強的注解 3.獲取DeclareParents //與普通getAdvisors相像 getDelaredParentsAdvisor()}; 2.2 找到滿足我們配置的通配符的增強器findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName){ 遍歷candidateAdvisors 1.先處理引介增強 canApply{} 2.處理普通bean的增強 canApply{}};3.createProxy(){ proxyFactory=new ProxyFactory(); 1.//獲取當前類中相關屬性 proxyFactory.copyFrom(this); 2.//添加代理接口 proxyFactory.addInterface(targetInterFace of targetInterfaces); 3.//將攔截器(各種攔截器,增強器,增強方法)統一封裝為Advisor,並加入ProxyFactory中。 advisors = buildAdvisors(beanName, specificInterceptors){ 1.處理commonIntercepotors和specficInterceptor,加入allInterceptors中, //將攔截器(各種攔截器,增強器,增強方法)統一封裝為Advisor 2.advisros[i]=this.advisorAdapterRegistry.wrap(allInterceptors.get(i)){ 根據傳入參數類型是 a.Advisor (直接返回) b.Advice--1.MethodInterceptor...2.AdvisorAdapter DefaultPointcutAdvisor c.其他類型拋出異常 }; }; //加入ProxyFactory中 proxyFactory.addAdvisor(advisor of advisors); 4.//設置要代理的類 proxyFactory.setTargetSource(targetSource); 5.//定制代理的一些屬性 customizeProxyFactory(proxyFactory); 6.//獲取代理並返回 AopProxy return ProxyFactory.getProxy(this.proxyClassLoader){ //創建代理 1.return createAopProxy().getProxy(classLoader); { }; };};3.6.1.1createAopProxy(){ getAopProxyFactory().createAopProxy(this){ if(根據條件,選取代理方法 1.JDK動態代理,2.CGLIB) new JdkDynamicAopProxy(config); new CglibProxyFactory.createCglibProxy(config);}
1.6.3 JDK動態代理和Cglib代理
1.JDK動態代理和Cglib的區別
JDK動態代理針對接口,無法針對類。目標類實現了接口,默認采用該方式。沒有實現必須CGLIB; CGLIB是針對類,生成子類,覆蓋方法,所以原類中的方法不能是final
2.JdkDynamicAopProxy
示例
public interface UserService{
public abstract void add();
}
public class UserServiceImpl implements UserService{
public void add(){
System.out.println("-------------add-----------");
}
}
//創建自定義的InvocationHandler,用於對接口的方法增強
//必須重寫的三個函數
public class MyInvocationHandler implements InvocatinHandler{
private Object target;
1.//將被代理對象傳入
public MyInvocationHandler(Object target){
super();
this.target = target;
}
2.獲取代理對象
public Object getProxy(){
return Proxy.newProxyInstance(classLoader, target.getClass().getInterfaces(),this);
}
3.執行目標對象方法
public Object invoke(Object proxy, Method method, Object[] args){
System.out.println("-------------add-----------");
Object result = method.invoke(target, args);
System.out.println("-------------add-----------");
return result;
}
}
3.jdk動態代理必須實現的三個接口
//必須重寫的三個函數
1.//將被代理對象傳入
public MyInvocationHandler(Object target)
2.獲取代理對象
public Object getProxy(){
3.執行目標對象方法
public Object invoke(Object proxy, Method method, Object[] args){
4.Spring AOP JdkDynamicAopProxy也實現了InvocationHandler接口
public object invoke(Object proxy, Method method, Object[] args){
1.....很多邏輯
2.獲取當前方法的攔截器鏈 //並封裝再ReflectiveMethodInvocation中
3.proceed() //執行攔截器鏈
}
5.CGLIB動態代理
委托給Cglib2AopProxy完成
getProxy(){
1.創建enhancer
Enhancer enhancer = new createEnhancer();
2.設置父類
enhancer.setSuperclass(proxySuperClass);
3.設置攔截器
Callback[] callbacks = getCallbacks();
enhancer.setCallbacks();
4.生成代理類,以及創建代理
proxy=enhancer.create();
}
