一、IOC(Inversion of Control)或者依賴注入(Dependency Injection)
1、底層實現原理:反射
2、三大核心接口:
BeanFactory:簡單容器系列,只是實現了容器最基本的功能。
ApplicationContext:應用上下文,作爲容器的高級形態存在。除了具有基本的功能外,還增加了許多面向框架的特性,同時對應用環境做了許多適配。
WebApplicationContext:JavaWeb項目容器。
3、IOC 容器的初始化過程分爲三步驟:Resource 定位、BeanDefinition 的載入和解析,BeanDefinition 註冊。
ClassPathResource resource = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
3.1、Resource 定位:獲取bean文件的輸入流;
3.2、BeanDefinition 載入和解析:BeanDefinitionReader 讀取、解析 Resource 資源,也就是將用戶定義的 Bean 表示成 IOC 容器的內部數據結構:BeanDefinition
a、根據 xml獲取相應的 Document 對象(DocumentBuilderFactory文件解析工廠)
b、對四大標籤:import、alias、bean、beans 進行解析,利用反射生成對象
3.3、BeanDefinition 註冊: 向IOC容器註冊第二個過程解析得到的 BeanDefinition ,即注入到一個 Map 容器中(IOC 容器內部維護着一個 ConcurrentHashMap 數據結構,key爲beanName,value爲BeanDefinition)。可以通過bean的lazyinit屬性控制依賴關係是在容器初 始化還是第一次調用 getBean() 向容器索要時完成。
二、AOP(Aspect Oriented Programming)
1、介紹:Spring中AOP代理由Spring的IOC容器負責生成、管理,其依賴關係也由IOC容器負責管理。因此,AOP代理可以直接使用容器中的其它bean實例作爲目標,這種關係可由IOC容器的依賴注入提供。
AOP實現的關鍵在於AOP框架自動創建的AOP代理,AOP代理主要分爲靜態代理和動態代理,靜態代理的代表爲AspectJ(AspectJ在編譯時就增強了目標對象);而動態代理則以Spring AOP爲代表,AOP框架:AspectJ,JBoss AOP,JBoss AOP
2、Spring AOP動態代理中的兩種主要方式:
JDK動態代理: 其代理對象必須是某個接口的實現,它是通過在運行期間創建一個接口的實現類來完成對目標對象的代理;其核心的兩個類是InvocationHandler和Proxy, 是由java內部的反射機制來實現的。
CGLIB代理: 實現原理類似於JDK動態代理,只是它在運行期間生成的代理對象是針對目標類擴展的子類。CGLIB是高效的代碼生成包,底層是依靠ASM(開源的java字節碼編輯類庫)操作字節碼實現的,性能比JDK強;需要引入包asm.jar和cglib.jar。
Java 字節碼操控框架(ASM和Javassist):在代碼裏生成字節碼,並動態地加載成class對象、創建實例。即在運行期系統中,遵循Java編譯系統組織.class文件的格式和結構,生成相應的二進制數據,然後再把這個二進制數據加載轉換成對應的類,這樣,就完成了在代碼中,動態創建一個類的能力了。ASM:在創建class字節碼的過程中,操縱的級別是底層JVM的彙編指令級別,這要求ASM使用者要對class組織結構和JVM彙編指令有一定的瞭解。Javassist:直接使用java編碼的形式,不需要了解虛擬機指令。
3、配置方式:
3.1、工廠bean(編碼)配置方式:
<bean id="userLogin" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"value="com.aop.proxyFactory.UserLogin"/>
<property name="target" ref="target"/>
<property name="interceptorNames" value="beforeAdviser" />
</bean>
3.2、xml配置方式
<aop:config>裏面有一個"proxy-target-class"屬性,true代表使用CGLIB生成代理,false(默認)則基於jdk代理
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/>
<aop:aspect ref="aspectSupportBean">
<aop:before pointcut-ref="pointcut" method="before"/>
</aop:aspect>
</aop:config>
3、aspect註解
@Aspect
@Service
public class XmlAopDemoUserLog {
// 配置切點 及要傳的參數
@Pointcut("execution(* com.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
public void pointCut(int id){}
// 配置連接點 方法開始執行時通知
@Before("pointCut(id)")
public void beforeLog(int id) {
System.out.println("開始執行前置通知 日誌記錄:"+id);
}
}
三、Spring生命週期
1、BeanFactoryPostProcessor:postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)實例任何bean之前,加載和修改配置信息。
2、Bean的實例化:反射
3、Bean屬性注入:反射屬性及依賴Bean的注入
4、BeanNameAware:setBeanName(String name)
5、BeanFactoryAware:setBeanFactory(BeanFactory beanFactory)
6、ApplicationContextAware: setApplicationContext(ApplicationContext applicationContext)
7、BeanPostProcessor:postProcessBeforeInitialization(Object bean, String beanName)
8、postProcessBeforeInitialization():afterPropertiesSet()
9、init-method()
10、BeanPostProcessor:postProcessorAfterInitialization(Object bean, String beanName)
11、使用Bean:
12、DisposableBean:destory()
13、destory-method()
說明:
1、容器級生命週期接口(一般稱它們的實現類爲“後處理器”):BeanFactoryPostProcessor接口與BeanPostProcessor,它們的作用範圍是整個上下文環境。使用方法是單獨新增一個類來實現這些接口,那麼在處理其他Bean的某些時刻就會回調響應的接口中的方法。
2、Bean生命週期接口:BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean、DiposableBean,它們的作用範圍的Bean範圍,即僅僅對實現了該接口的指定Bean有效,所有其使用方法是在要使用該功能的Bean自己來實現該接口。
3、Bean自身的方法:init-method(),destory-method()。
Ref:
https://www.jianshu.com/p/94ec7f1c3afd