1.spring ioc 原理
a.詳細原理分析:https://www.cnblogs.com/ITtangtang/p/3978349.html?clicktime=1583239891&enterid=1583239891#a4
b.粗略原理
bean注冊:
1.Spring IoC容器根據(jù)定位的Bean定義資源文件装诡,將其加載讀入并轉(zhuǎn)換成為Document對象過程完成妈拌。
2.經(jīng)過對Spring Bean定義資源文件轉(zhuǎn)換的Document對象中的元素層層解析,Spring IoC現(xiàn)在已經(jīng)將XML形式定義的Bean定義資源文件轉(zhuǎn)換為Spring IoC所識別的數(shù)據(jù)結(jié)構(gòu)——BeanDefinition纵东。
3.BeanDefinition注冊過程就是在 IOC 容器內(nèi)部維護的一個HashMap 來保存得到的 BeanDefinition 的過程招盲。
依賴注入:
時機:
(1).用戶第一次通過getBean方法向IoC容索要Bean時愿题,IoC容器觸發(fā)依賴注入免胃。
(2).當(dāng)用戶在Bean定義資源中為<Bean>元素配置了lazy-init屬性粉楚,即讓容器在解析注冊Bean定義時進行預(yù)實例化辣恋,觸發(fā)依賴注入。
對使用工廠方法和自動裝配特性的Bean的實例化相當(dāng)比較清楚模软,調(diào)用相應(yīng)的工廠方法或者參數(shù)匹配的構(gòu)造方法即可完成實例化對象的工作伟骨,但是對于我們最常使用的默認無參構(gòu)造方法就需要使用相應(yīng)的初始化策略(JDK的反射機制或者CGLIB)來進行初始化。
在Spring中燃异,有兩個很容易混淆的類:BeanFactory和FactoryBean携狭。
BeanFactory:Bean工廠,是一個工廠(Factory)回俐,我們Spring IoC容器的最頂層接口就是這個BeanFactory逛腿,它的作用是管理Bean,即實例化仅颇、定位单默、配置應(yīng)用程序中的對象及建立這些對象間的依賴。
FactoryBean:工廠Bean忘瓦,是一個Bean搁廓,作用是產(chǎn)生其他bean實例。通常情況下耕皮,這種bean沒有什么特別的要求境蜕,僅需要提供一個工廠方法,該方法用來返回其他bean實例凌停。通常情況下汽摹,bean無須自己實現(xiàn)工廠模式,Spring容器擔(dān)任工廠角色苦锨;但少數(shù)情況下逼泣,容器中的bean本身就是工廠,其作用是產(chǎn)生其它bean實例舟舒。
當(dāng)用戶使用容器本身時拉庶,可以使用轉(zhuǎn)義字符”&”來得到FactoryBean本身,以區(qū)別通過FactoryBean產(chǎn)生的實例對象和FactoryBean對象本身秃励。在BeanFactory中通過如下代碼定義了該轉(zhuǎn)義字符:
StringFACTORY_BEAN_PREFIX = "&";
如果myJndiObject是一個FactoryBean氏仗,則使用&myJndiObject得到的是myJndiObject對象,而不是myJndiObject產(chǎn)生出來的對象。
2.Springboot原理
1.參考
http://www.reibang.com/p/464d04c36fb1
https://cloud.tencent.com/developer/article/1449134
2.粗略原理
@SpringBootApplicationg有三個主要注解
1.@SpringBootConfiguration
其內(nèi)部主要注解為@Configuration
其作用就是注冊為配置類皆尔,掃描其中@Bean注解添加到ioc容器中相當(dāng)于使用xml的方式進行bean注冊呐舔。
2.@ComponentScan
該注解負責(zé)掃描包中的類似@Component,@Controller等注冊到ioc容器中。
3.@EnableAutoConfiguration
其中包括@AutoConfigurationPakage和@Import(AutoConfigurationImportSelector.class)
@AutoConfigurationPakage它其實返回了當(dāng)前主程序類的 同級以及子級的包組件
AutoConfigurationImportSelector這個類繼承了 DeferredImportSelector 繼承了 ImportSelector慷蠕,其中selectImports方法會從META-INF/spring.factories外部文件掃描內(nèi)容珊拼,以鍵值對的形式將用將所有符合條件的@Configuration配置都加載到當(dāng)前SpringBoot創(chuàng)建并使用的IoC容器。
3.Spring Aop原理
1.參考
https://blog.csdn.net/weixin_40160543/article/details/92010760
https://www.cnblogs.com/liuyk-code/p/9886033.html
http://www.pianshen.com/article/4914369461/
http://www.reibang.com/p/b6d3e5a0c7e2
2.粗略原理
1.aop配置類向ioc容器注冊
AnnotationAwareAspectJAutoProxyCreator
2.獲取容器中的bean對象流炕,注冊后置處理器澎现,將增強轉(zhuǎn)換為攔截器,組成攔截器鏈
3.遍歷所有bean對象每辟,在創(chuàng)建前判斷是否需要增強剑辫。如果需要就創(chuàng)建bean的代理對象。
4.返回普通的bean對象和代理對象渠欺。
4.myBatis原理
1.代理實現(xiàn)
mybatis通過Proxy類將mapper接口解析并放回代理對象
sqlSession原理:
package com.cwh.XiaohaoMybatis;
import java.lang.reflect.Proxy;
public class XiaohaoSession {
public static Object getMapper(Class clazz){
Class[] classes = new Class[]{clazz};
Object objecy = Proxy.newProxyInstance(XiaohaoSession.class.getClassLoader(), classes, new XiaohaoInvocationHandler());
return objecy;
}
}
具體實現(xiàn)sql
package com.cwh.XiaohaoMybatis;
import org.apache.ibatis.annotations.Select;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class XiaohaoInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Select annotation = method.getAnnotation(Select.class);
if(null!=annotation){
System.out.println("sql---"+annotation.value()[0]);
}
return null;
}
}
2.與spring結(jié)合
mybatis需要將代理對象交給ioc容器
借助factoryBean可以將放回每一個mapper接口的代理對象
package com.cwh.XiaohaoMybatis;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
public class XiaohaoMaperFactoryBean implements FactoryBean {
Class mapperClass;
XiaohaoMaperFactoryBean(Class mapperClass){
this.mapperClass = mapperClass;
}
@Override
public Object getObject() throws Exception {
return XiaohaoSession.getMapper(mapperClass);
}
@Override
public Class<?> getObjectType() {
return mapperClass;
}
}
借助BeanDefinitionRegistrar可以將每個由factoryBean產(chǎn)生的代理對象注冊到ioc中
package com.cwh.XiaohaoMybatis;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class XiaohaoBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(XiaohaoMaperFactoryBean.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
//可以循環(huán)注冊出每個mapper
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.cwh.XiaohaoMybatis.XiaohaoMapper");
beanDefinitionRegistry.registerBeanDefinition("XiaoHaoMapper",beanDefinition);
}
}
需要在配置類中告知spring
package com.cwh.XiaohaoMybatis;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan("com.cwh")
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@Import(XiaohaoBeanDefinitionRegistrar.class)
public class SpringConfig {
}
主測試類
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
XiaohaoServlet xiaohaoServlet = ac.getBean(XiaohaoServlet.class);
System.out.println(xiaohaoServlet);
xiaohaoServlet.queryAll();
}