Spring中應用反射機制淺析

我們知道,Spring中大量使用了反射機制,那么究竟是什么地方使用了呢?就從源頭說起吧。

?

一? 反射源頭Class類

對類的概念我們已經非常熟悉了。比如可以有Student這個類,Person這個類。但是我們要知道,有一個叫Class的類,它是反射的源頭。

?

正常方式:通過完整的類名—>通過new實例化—>取得實例化對象

反射方式:實例化對象—>getClass()方法—>通過完整的類名

?

一個簡單的例子:

package cn.classes;

public class OneClass {

}


package cn.test;

import cn.classes.OneClass;

public class Test {
??? public static void main(String[] args) {
??????? OneClass c = new OneClass();
????????System.out.println(c.getClass().getName());
?? }
}

輸出結果:cn.classes.OneClass


我們需要使用反射,就要獲得Class這個類,有三種方法:

package cn.classes;

public class OneClass {

}


import cn.classes.OneClass;

public class Test {
public static void main(String[] args) {
???? Class<?> c1 = null;
???? Class<?> c2 = null;
???? Class<?> c3 = null;

???? try?
??? {
???????? // 方法一:forName(重要)
?????????c1 = Class.forName("cn.classes.OneClass");
?? ?}?
??? catch (ClassNotFoundException e)?
??? {
???????? e.printStackTrace();
????}
???? // 方法二
?????c2 = new OneClass().getClass();
??
???? // 方法三
?????c3 = OneClass.class;

???? System.out.println(c1.getName());
???? System.out.println(c2.getName());
???? System.out.println(c3.getName());
?? }
}

輸出結果:cn.classes.OneClass

?

?

二 利用Class這個類實例化類

①無參構造

package cn.classes;

public class Person {
??? private String name;
??? private int age;

???? .............省略getter,setter..............

??? @Override
??? public String toString()
??? {
????????? return "Person [name=" + name + ", age=" + age + "]";
??? }

}


package cn.test;

import cn.classes.Person;

public class Test
{
??? // 這樣做必須在類中有一個空構造方法
??? public static void main(String[] args)
??? {
????????????? Class<?> c = null;
?????????????? try
?????????????? {
??????????????????????c = Class.forName("cn.classes.Person");
??????????????????????Person p = (Person)c.newInstance();
????????????????????? p.setName("xy");
????????????????????? p.setAge(20);
????????????????????? System.out.println(p);
?????????????? }?
????????????? catch (Exception e)
????????????? {
????????????????????? e.printStackTrace();
????????????? ?}??
???? }
}

?

②有參構造

package cn.classes;

public class Person
{
??? private String name;
??? private int age;

?????public Person(Stringname,int age){

???????????????? this.name = name;

???????????????? this.age = age;

????}

??? .............省略getter,setter..............????

??? @Override
??? public String toString()
??? {
????????? return "Person [name=" + name + ", age=" + age + "]";
??? }
}


package cn.test;

import java.lang.reflect.Constructor;

import cn.classes.Person;

public class Test
{
??? // 如果沒有一個空構造方法
??? public static void main(String[] args)
??? {
????????? Class<?> c = null;
????????? try
??????????{
??????????????????c = Class.forName("cn.classes.Person");
??????????????????Constructor<?> con = c.getConstructors(String.class,int.class);
??????????????????Person p = (Person)con.newInstance("xy",20);
????????????????? System.out.println(p);
????????? }?
???????? catch (Exception e)
???????? {
??????????????? e.printStackTrace();
???????? }??
??? }
}

?

三 Spring中使用Class實例化

bean.xml
<bean id="id" class="com.xy.Student" />

?

Spring將采用的代碼創建代碼Java實例
Class c = Class.forName("com.xy.Student");
Object bean = c.newInstance();

?

?

四 Class類調用方法

package cn.classes;

public class Person
{
??? public void add()
??? {
?????????? System.out.println("add");
??? }

??? public void addWithParameters(String name, int age)
??? {
??????????? System.out.println("add帶參數方法" + name + age);
??? }
}


package cn.test;

import java.lang.reflect.Method;

public class Test
{
??? public static void main(String[] args)
??? {
???????????? Class<?> c1 = null;
?????????????try
???????????? {

?????????????????? c1 = Class.forName("cn.classes.Person");

?????????????????? // 不帶參數的方法調用
???????????????????Method m = c1.getMethod("add");
???????????????????m.invoke(c1.newInstance());

?

?????????????????? // 帶參數方法調用
???????????????????Method m1 = c1.getMethod("addWithParameters", String.class,?int.class);
???????????????????m1.invoke(c1.newInstance(), "xy", 22);
?????????? ?}
??????????? catch (Exception e)
??????????? {
?????????????????? e.printStackTrace();
??????????? }
??? }
}

?

?

五 Class獲得getter,setter方法

Class這個類可以獲得類的很多信息,比如獲得該類的接口,構造函數,屬性,方法等。我們來看如何獲得getter,setter方法。

package cn.classes;

public class Person
{
??? private String name;
??? private int age;

??? 省略getter,setter??

?}

?

package cn.test;

import java.lang.reflect.Method;

public class Test
{
??? public static void main(String[] args)
??? {
?????????? Class<?> c1 = null;
?????????? Object obj = null;
?????????? try
?????????? {
???????????????????? c1 = Class.forName("cn.classes.Person");
???? ??????????????? obj = c1.newInstance();
???????????????????? setter(obj, "name", "xy", String.class);
???? ??????????????? setter(obj, "age", 20, int.class);
???????????????????? getter(obj, "name");
???????????????????? getter(obj, "age");
?????????? }
?????????? catch (Exception e)
??????????? {
???? ?????????????? e.printStackTrace();
??????????? }
?? }

?? /**
??? * @param obj:要操作的對象
??? * @param att:要操作的屬性
??? * @param value:要設置的屬性內容
??? * @param type:要設置的屬性類型
??? */
??? public static void setter(Object obj, String att, Object value, Class<?> type)
??? {
???????? try
? ?????? {
??????????? // 得到setter方法
???? ???? Method m = obj.getClass().getMethod("set" + initStr(att), type);
???? ???? m.invoke(obj, value);
???????? }
???????? catch (Exception e)
???????? {
???? ???? e.printStackTrace();
???????? }
?? }

?? /**
??? * @param obj:要操作的對象
??? * @param att:要操作的屬性
??? */
?? public static void getter(Object obj, String att)
?? {
??????? try
??????? {
?????????????? // 得到getter方法
???? ????????? Method m = obj.getClass().getMethod("get" + initStr(att));
???? ????????? System.out.println(m.invoke(obj));
?????? ?}
?????? catch (Exception e)
?????? {
???? ????????? e.printStackTrace();
?????? }
?? }

?? public static String initStr(String oldStr)
?? {
???????? String newStr = oldStr.substring(0, 1).toUpperCase() + oldStr.substring(1);
???????? return newStr;
?? }
}

?

六 Spring調用getter,setter方法

我們以setter注入例子

bean.xml
<bean id="id" class="com.xy.Student">
????<property name="stuName" value="xy" />
</bean>


Spring將采用的代碼創建代碼Java實例,并注入值:
Class c = Class.forName("com.xy.Student");
Object bean = c.newInstance();


通過一些操作獲取對stuName對應的setter方法名
String setname = "set" + "StuName";
Method method = c.getMehod(setname,String.Class);
method.invoke(bean,"xy");

這樣就完成了最基本的注入操作。當然,Spring還可以通過構造函數進行注入。這樣就參考第二點有參構造的Class的使用。

Class還可以訪問Annotation,這樣就Spring使用注解的時候,可以完成注入的功能。

?

七 總結

反射的內容還是很多的,需要系統的學習。當然,Spring也是。

本文轉自IT徐胖子的專欄博客51CTO博客,原文鏈接http://blog.51cto.com/woshixy/1060263如需轉載請自行聯系原作者


woshixuye111

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540101.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540101.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540101.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ios nslog 例子_iOS開發-使用宏自定義輸出(NSLog)

前言&#xff1a;1)輸出日志是會大量損耗系統性能2)輸出的信息很容易會被截取到&#xff0c;導致信息不安全。所以我們會在發行版(Release)取消所有的Log。如果一行一行地去注釋掉Log&#xff0c;顯然不是一個明確的選擇。因此我們可以使用宏去自定義Log輸出。最簡單的一個例子…

python小技巧積累--題庫(持續更新)

介紹 作為一名程序員&#xff0c;除了需要具備解決問題的思路以外&#xff0c;代碼的質量和簡潔性也很關鍵。 python內置庫中就有很多簡潔而又優雅的操作&#xff0c;這里的知識都來源于網絡積累&#xff0c; 閑暇時整理下來方便溫故。目錄 >選擇正確的內置功能 使用enum…

提高SQL執行性能方案:如何讓你的SQL運行得更快

---- 人們在使用SQL時往往會陷入一個誤區&#xff0c;即太關注于所得的結果是否正確&#xff0c;而忽略了不同的實現方法之間可能存在的性能差異&#xff0c;這種性能差異在大型的或是復雜的數據庫環境中&#xff08;如聯機事務處理OLTP或決策支持系統DSS&#xff09;中表現得尤…

休眠后gpio狀態_STM32中GPIO的8種工作模式總結

STM32中GPIO的8種工作模式總結一、推挽輸出&#xff1a;可以輸出高、低電平&#xff0c;連接數字器件;推挽結構一般是指兩個三極管分別受兩個互補信號的控制&#xff0c;總是在一個三極管導通的時候另一個截止。高低電平由IC的電源決定。形象點解釋&#xff1a;推挽&#xff0c…

Ubuntu16.04 下 tensorRT安裝

環境準備 主要是根據工程環境需要&#xff0c;參考trt文檔安裝trt 1.查看trt適配情況 &#xff1a;鏈接跳轉&#xff0c;注意&#xff0c;不同版本的trt有不同版本的文檔&#xff0c;請以最新文檔為準。 2.根據自己系統情況下載相關包 因為我自己拉的docker鏡像是ubuntu16.04…

左右xcode的重構選項的一些理解

Rename(重命名):對標示符進行重命名,以獲得更好的代碼可讀性,這些標示符包含類,方法或者函數的名稱. Extract(抽取):將你在XCode種選擇的代碼抽取到一個新的方法或函數中. Create SuperClass(創建父類):為Xcode中當前所選的類定義父類 Move Up(上移):將所選擇的方法,屬性,或實例…

window 如何查看tomcat 實時日志_如何處理生產環境Tomcat的catalina.out日志?

前語&#xff1a;不要為了讀文章而讀文章&#xff0c;一定要帶著問題來讀文章&#xff0c;勤思考。作者&#xff1a;jmcui 來源&#xff1a;http://1t.click/x4q# 前言隨著每天業務的增長&#xff0c;Tomcat 的catalina.out日志 變得越來越大&#xff0c;占用磁盤空間不說。要…

zabbix的agent端的主動模式關鍵三個參數

如多主機超過300和隊列內容過多,就采用主動模式. [rootweb03 zabbix]# egrep -v "^#|^$" zabbix_agentd.conf PidFile/var/run/zabbix/zabbix_agentd.pid LogFile/var/log/zabbix/zabbix_agentd.log LogFileSize0 StartAgents0 ServerActive172.16.1.8 Hostnameweb03…

opencv 繪制坐標曲線_OpenCV手工實現灰度及RGB直方圖

#include #include#include#include#include#include#include#include#includeusing namespacecv;using namespacestd;//單通道圖片直方圖繪制void drawHist(vectornums){Mat hist Mat::zeros(600, 800, CV_8UC3);auto Max max_element(nums.begin(), nums.end());//max迭代器類…

onnx 測試_用于ONNX的TensorRT后端

用于ONNX的TensorRT后端解析ONNX模型以使用TensorRT執行。另請參閱TensorRT文檔。有關最近更改的列表&#xff0c;請參見changelog。支持的TensorRT版本Master分支上的開發適用于具有完整維度和動態架構shape支持的TensorRT 7.2.1的最新版本。對于TensorRT的早期版本&#xff0…

paddlepaddle測試安裝_百度paddlepaddle深度學習7日入門-CV疫情特輯心得

正值疫情嚴重之日&#xff0c;作為一名研究生被迫待在家里學習&#xff0c;手頭的科研項目也嚴重受挫。。。偶然間&#xff0c;看到微信公眾號發布這門課&#xff0c;馬上報名&#xff0c;入坑&#xff01;&#xff01;&#xff01;瞬間疫情其間有學習的目標了。。該課程學習依…

apache目錄 vscode_VsCode搭建Java開發環境(Spring Boot項目創建、運行、調試)

VsCode搭建Java開發環境(Spring Boot項目創建、運行、調試)安裝如下兩個主要擴展即可&#xff0c;這兩個擴展已關聯java項目開發主要使用的maven、springboot等所需要的擴展。開始步驟&#xff1a;在 Visual Studio Code 中打開擴展視圖(CtrlShiftX)。輸入“java”搜索商店擴展…

android dp轉px的公式_Android特效專輯——自定義不一樣的Toast

大家都知道&#xff0c;Android的控件有時候很難滿足我們的需求&#xff0c;所以我們需要自定義View。自定義的方式很多&#xff0c;有繼承原生控件也有直接自定義View的&#xff0c;今天寫的是自定義的Toast&#xff0c;當然&#xff0c;這個不是復寫Toast,是換一種表達形式&a…

code iban 是有什么組成_深入淺出Zookeeper(四):客戶端的請求在服務器中經歷了什么...

作者 泊浮目 沃趣科技高級研發工程師出品 沃趣科技1. 前言當我們向zk發出一個數據更新請求時&#xff0c;這個請求的處理流程是什么樣的&#xff1f;zk又是使用了什么共識算法來保證一致性呢&#xff1f;帶著這些問題&#xff0c;我們進入今天的正文。2. 設計模式&#xff1…

Centos7: 配置IO調度

今天有同事問我個問題&#xff1a;“CentOS7如何修改IO默認的調度”&#xff0c;我這里簡單整理下如何調整的方法&#xff1a; 1、查看CentOS7下IO支持的調度 1234[rootkvm02 ~]# dmesg | grep -i scheduler [ 16.900459] io scheduler noop registered[ 16.900473] io sch…

啟動activemq_「Java」 - SpringBoot amp; ActiveMQ

一、消息隊列消息隊列中間件是分布式系統中重要的組件&#xff0c;主要解決應用耦合、異步消息、流量削鋒等問題&#xff0c;實現高性能、高可用、可伸縮和最終一致性架構&#xff0c;是大型分布式系統不可缺少的中間件。目前在生產環境中使用較多的消息隊列有ActiveMQ、Rabbit…

永不休眠怎么設置_電腦休眠后應該怎樣喚醒?

可能有朋友會碰到這種情況&#xff0c;電腦屏幕顯示正在休眠&#xff0c;而且不停的轉圈&#xff0c;這是怎么回事&#xff0c;如何喚醒?下面讓堅哥為大家分析一下吧。電腦開機顯示休眠一般根據以下幾種情況進行處理&#xff1a;1、正常電腦休眠&#xff1a;一般的是按一下電源…

配置ssl證書_Mysql配置ssl證書

本環境基于mysql5.6配置&#xff0c;通過openssl生成證書進行配置一、確認環境信息1、查看數據庫版本mysql> select version();-----------| version() |-----------| 5.6.36 |-----------2、查看數據庫是否支持ssl配置mysql> show variables like have%ssl%;-----------…

echarts散點圖中大小_echarts在地圖上繪制散點圖(任意點)

項目需求&#xff1a;在省份地圖上繪制散點圖&#xff0c;散點位置不一定是哪個城市或哪個區縣&#xff0c;即任意點通過查詢官網文檔&#xff0c;找到一個與需求類似的demo&#xff1a;&#xff0c;更改代碼&#xff0c;將中國地圖替換為省份地圖&#xff0c;省份地圖的js代碼…

如何讓圖片充滿excel單元格_如何在Excel單元格建立下拉菜單

對于一些常用的數據我們往往會希望能夠盡量快速的輸入&#xff0c;下拉菜單就是一個最簡單的解決辦法。那么如何實現下拉菜單呢&#xff1f;跟隨以下步驟&#xff0c;建立屬于自己的下拉菜單吧&#xff01;如何建立下拉菜單&#xff1f;一、確定內容&#xff1a;在單元格中&…