spring (反射+代理+DI+AOP)


spring  https://baijiahao.baidu.com/s?id=1620606848227713760&wfr=spider&for=pc

反射 https://blog.csdn.net/ritterliu/article/details/7764849

1. 反射

反射屬於動態編譯,就是在編譯期並不確定是哪個類被加載了,而是在程序運行的時候才加載,所以我們可以動態的解剖一個類,獲取這個類的任意屬性和方法。

  1.1獲取類對象

      類名.class

      對象.getClass()

      Class.forName("全類名")

 

2、Spring是什么?

Spring是一個輕量級的IoC和AOP容器框架。是為Java應用程序提供基礎性服務的一套框架,目的是用於簡化企業應用程序的開發,它使得開發者只需要關心業務需求。常見的配置方式有三種:基於XML的配置、基於注解的配置、基於Java的配置。

主要由以下幾個模塊組成:

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實現。

3、Spring 的優點?

(1)spring屬於低侵入式設計,代碼的污染極低;

(2)spring的DI機制將對象之間的依賴關系交由框架處理,減低組件的耦合性;

(3)Spring提供了AOP技術,支持將一些通用任務,如安全、事務、日志、權限等進行集中式管理,從而提供更好的復用。

(4)spring對於主流的應用框架提供了集成支持。

(5)獨立於各種應用服務器

4、什么是DI機制

依賴注入(Dependecy Injection)和控制反轉(Inversion of Control)是同一個概念,具體的講:當某個角色需要另外一個角色協助的時候,在傳統的程序設計過程中,

通常由調用者來創建被調用者的實例。但在spring中創建被調用者的工作不再由調用者來完成,因此稱為控制反轉。創建被調用者的工作由spring來完成,然后注入調用者
因此也稱為依賴注入。
spring以動態靈活的方式來管理對象 , 注入的兩種方式,設置注入和構造注入。
設置注入的優點:直觀,自然
構造注入的優點:可以在構造器中決定依賴關系的順序。

5. 什么是 Spring AOP?

  或許你可以給面試官舉個例子:歌星都有好多助理,歌星最重要的一件事就是唱歌,其他事他不用關注,比如唱歌前可能需要和其他人談合作,還要布置場地,唱歌后還要收錢等等,這些統統交給他對應的助理去做。

也許哪一天,這個歌星做慈善,免費唱歌了,不收錢了,那么就可以把收錢這個助力給辭退了。這就是 AOP,每個人各司其職,靈活組合,達到一種可配置的、可插拔的程序結構。AOP 的實現原理就是代理模式。

在程序中也是如此,通過代理,可以詳細控制訪問某個或者某類對象的方法,在調用這個方法前做前置處理,調用這個方法后做后置處理。

https://blog.csdn.net/qq_32317661/article/details/82878679  aop 

https://blog.csdn.net/q982151756/article/details/80513340  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"/>)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM