spring https://baijiahao.baidu.com/s?id=1620606848227713760&wfr=spider&for=pcjava
反射 https://blog.csdn.net/ritterliu/article/details/7764849程序員
1. 反射面試
反射屬於動態編譯,就是在編譯期並不肯定是哪一個類被加載了,而是在程序運行的時候才加載,因此咱們能夠動態的解剖一個類,獲取這個類的任意屬性和方法。spring
1.1獲取類對象設計模式
類名.class安全
對象.getClass()服務器
Class.forName("全類名")框架
二、Spring是什麼?ide
Spring是一個輕量級的IoC和AOP容器框架。是爲Java應用程序提供基礎性服務的一套框架,目的是用於簡化企業應用程序的開發,它使得開發者只須要關心業務需求。常見的配置方式有三種:基於XML的配置、基於註解的配置、基於Java的配置。this
主要由如下幾個模塊組成:
Spring Core:核心類庫,提供IOC服務;
Spring Context:提供框架式的Bean訪問方式,以及企業級功能(JNDI、定時任務等);
Spring AOP:AOP服務;
Spring DAO:對JDBC的抽象,簡化了數據訪問異常的處理;
Spring ORM:對現有的ORM框架的支持;
Spring Web:提供了基本的面向Web的綜合特性,例如多方文件上傳;
Spring MVC:提供面向Web應用的Model-View-Controller實現。
三、Spring 的優勢?
(1)spring屬於低侵入式設計,代碼的污染極低;
(2)spring的DI機制將對象之間的依賴關係交由框架處理,減低組件的耦合性;
(3)Spring提供了AOP技術,支持將一些通用任務,如安全、事務、日誌、權限等進行集中式管理,從而提供更好的複用。
(4)spring對於主流的應用框架提供了集成支持。
(5)獨立於各類應用服務器
四、什麼是DI機制
依賴注入(Dependecy Injection)和控制反轉(Inversion of Control)是同一個概念,具體的講:當某個角色須要另一個角色協助的時候,在傳統的程序設計過程當中,
一般由調用者來建立被調用者的實例。但在spring中建立被調用者的工做再也不由調用者來完成,所以稱爲控制反轉。建立被調用者的工做由spring來完成,而後注入調用者
所以也稱爲依賴注入。
spring以動態靈活的方式來管理對象 , 注入的兩種方式,設置注入和構造注入。
設置注入的優勢:直觀,天然
構造注入的優勢:能夠在構造器中決定依賴關係的順序。
5. 什麼是 Spring AOP?
或許你能夠給面試官舉個例子:歌星都有好多助理,歌星最重要的一件事就是唱歌,其餘事他不用關注,好比唱歌前可能須要和其餘人談合做,還要佈置場地,唱歌后還要收錢等等,這些通通交給他對應的助理去作。
也許哪一天,這個歌星作慈善,免費唱歌了,不收錢了,那麼就能夠把收錢這個助力給辭退了。這就是 AOP,每一個人各司其職,靈活組合,達到一種可配置的、可插拔的程序結構。AOP 的實現原理就是代理模式。
在程序中也是如此,經過代理,能夠詳細控制訪問某個或者某類對象的方法,在調用這個方法前作前置處理,調用這個方法後作後置處理。
6. 談談你對代理模式(Spring AOP用的就是這種設計模式)的理解
代理模式的核心做用就是經過代理,控制對對象的訪問。它的設計思路是:定義一個抽象角色,讓代理角色和真實角色分別去實現它。
真實角色:實現抽象角色,定義真實角色所要實現的業務邏輯,供代理角色調用。它只關注真正的業務邏輯,好比歌星唱歌。
代理角色:實現抽象角色,是真實角色的代理,經過真實角色的業務邏輯方法來實現抽象方法,並在先後能夠附加本身的操做,好比談合同,佈置場地,收錢等等。
這就是代理模式的設計思路。代理模式分爲靜態代理和動態代理。靜態代理是咱們本身建立一個代理類,而動態代理是程序自動幫咱們生成一個代理,咱們就不用管了。下面我詳細介紹一下這兩種代理模式。
動態代理和靜態代理的區別
靜態:由程序員建立代理類對其編譯。在程序運行前代理類的.class文件就已經存在了。
動態:在程序運行時運用反射機制動態建立而成。
7. 靜態代理
靜態代理須要建立真實角色和代理角色,分別實現唱歌這個接口,真實角色很簡單,直接實現便可,由於真實角色的主要任務就是唱歌。
代理類就須要作點工做了,咱們思考一下,代理只是在明星唱歌先後作一些準備和收尾的事,唱歌這件事還得明星親自上陣,代理作不了。因此代理類裏面是確定要將真實的對象傳進來。
8. JDK 動態代理
既然動態代理不須要咱們去建立代理類,那咱們只須要編寫一個動態處理器就能夠了。真正的代理對象由 JDK 在運行時爲咱們動態的來建立。
具體實現:
1.定義接口類
2.定義接口實現類
3.定義動態代理類,實現 InvocationHandler 主要是實現 其中的invoke 其中是利用反射技術獲取代理類的方法,而後對方法增強
4. 客戶端調用
// 1.定義接口類 public interface IPerson { void say(); }
//2.定義接口實現類 public class Person implements IPerson { @Override public void say() { System.out.println("我是我的"); } }
//3.定義動態代理類,實現 InvocationHandler 主要是實現 其中的invoke 其中是利用反射技術獲取代理類的方法,而後對方法增強
public class ProxyForPerson implements InvocationHandler { IPerson person = null; // 關聯代理類和接口 public IPerson getProxyInterface(IPerson person) { this.person = person; return (IPerson) Proxy.newProxyInstance(person.getClass() .getClassLoader(), person.getClass() .getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("say".equals(method.getName())){ method.invoke(person, args); } return null; } } // 4. 客戶端調用 public class Client { public static void main(String[] args) { Person person = new Person(); ProxyForPerson proxy = new ProxyForPerson(); // 得到代理類 IPerson iperson = proxy.getProxyInterface(person); iperson.say(); } }
9.CGLIB 動態代理
CGLIB 採用了很是底層的字節碼技術,其原理是經過字節碼技術爲一個類建立子類,並在子類中採用方法攔截的技術攔截全部父類方法的調用,順勢織入橫切邏輯。但由於採用的是繼承,因此不能對final修飾的類進行代理
JDK動態代理和CGLIB動態代理的區別
JDK動態代理只能對實現了接口的類生成代理,而不能針對類 (缺點:也就是說它始終沒法擺脫僅支持 interface 代理的桎梏,由於它的設計就註定了這個遺憾。)
CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法(繼承),(缺點: 對於final修飾的方法沒法進行代理)
10.Spring AOP 採用哪一種代理?
在spring5 的源碼中,對於使用JDK的動態代理仍是CHLIB的代理,他會進行一個判斷hasNoUserSuppliedProxyInterfaces(config)
就是在判斷代理的對象是否有實現接口,有實現接口的話直接走 JDK 分支,即便用 JDK 的動態代理。
因此基本上能夠總結出 Spring AOP 中的代理使用邏輯了:若是目標對象實現了接口,默認狀況下會採用 JDK 的動態代理實現 AOP;若是目標對象沒有實現了接口,則採用 CGLIB 庫,Spring 會自動在 JDK 動態代理和 CGLIB 動態代理之間轉換。
咱們也能夠強制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)