當前位置:首頁 » 操作系統 » springdata源碼

springdata源碼

發布時間: 2022-08-25 16:28:54

㈠ 怎麼能讓spring框架載入加密後的.class文件

加密:使用AES加密,將文件的位元組碼讀取,對位元組碼進行加密後替換源文件

java代碼

/**

*

* 位元組加密

*/

public static byte[] encrypt(byte[] data, String key) throws Exception {

Key k = toKey(Base64.decode(key));

byte[] raw = k.getEncoded();

SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);

Cipher cipher = Cipher.getInstance(ALGORITHM);

cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

return cipher.doFinal(data);

}
/**
*
* 位元組加密
*/
public static byte[] encrypt(byte[] data, String key) throws Exception {
Key k = toKey(Base64.decode(key));
byte[] raw = k.getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return cipher.doFinal(data);
}

解密:

1、在tomcat的WebappClassLoader中修改源碼(自動義類載入器);

2、修改spring源碼Code包源碼。

加密方法

Java代碼

public static byte[] decrypt(byte[] data, String key) throws Exception {

Key k = toKey(Base64.decode(key));

byte[] raw = k.getEncoded();

SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);

Cipher cipher = Cipher.getInstance(ALGORITHM);

cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

return cipher.doFinal(data);

}
public static byte[] decrypt(byte[] data, String key) throws Exception {
Key k = toKey(Base64.decode(key));
byte[] raw = k.getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
return cipher.doFinal(data);
}

在 WebappClassLoader中解密

Java代碼

/**

* 判斷如需是需要解密的類進行數據處理

* */

//--------------------------------------start----------------------------------//

byte []data=null;

try {

if(isDecode(name)){

System.out.println("2818:--&&&-"+name);

data=AESUtils.decrypt(entry.binaryContent, key);

}else{

data=entry.binaryContent;

}

} catch (Exception e) {

e.printStackTrace();

}

try {

clazz = defineClass(name, data, 0,

data.length,

new CodeSource(entry.codeBase, entry.certificates));

//--------------------------------------end----------------------------------//
/**
* 判斷如需是需要解密的類進行數據處理
* */
//--------------------------------------start----------------------------------//
byte []data=null;
try {
if(isDecode(name)){
System.out.println("2818:--&&&-"+name);
data=AESUtils.decrypt(entry.binaryContent, key);
}else{
data=entry.binaryContent;
}
} catch (Exception e) {
e.printStackTrace();
}
try {
clazz = defineClass(name, data, 0,
data.length,
new CodeSource(entry.codeBase, entry.certificates));
//--------------------------------------end----------------------------------//

在spring的code包的SimpleMetadataReader修改器構造函數

Java代碼

// TODO 修改源碼判斷是否需要解密

SimpleMetadataReader(Resource resource, ClassLoader classLoader)

throws IOException {

InputStream is = resource.getInputStream();

ClassReader classReader = null;

try {

String name = "";

if (resource.getURI().toString().indexOf("jar:file") == -1) {

name = resource.getFile().getAbsolutePath();

if (!"".equals(name) && isDecode(name, cams)) {

byte[] data = inputStreamToByte(is);

try {

is = new ByteArrayInputStream(AESUtils.decrypt(data,

key));

// is = new ByteArrayInputStream(data);

} catch (Exception e) {

e.printStackTrace();

}

}

}

classReader = new ClassReader(is);

} finally {

is.close();

}
// TODO 修改源碼判斷是否需要解密
SimpleMetadataReader(Resource resource, ClassLoader classLoader)
throws IOException {
InputStream is = resource.getInputStream();
ClassReader classReader = null;
try {
String name = "";
if (resource.getURI().toString().indexOf("jar:file") == -1) {
name = resource.getFile().getAbsolutePath();
if (!"".equals(name) && isDecode(name, cams)) {
byte[] data = inputStreamToByte(is);
try {
is = new ByteArrayInputStream(AESUtils.decrypt(data,
key));
// is = new ByteArrayInputStream(data);
} catch (Exception e) {
e.printStackTrace();
}
}
}
classReader = new ClassReader(is);
} finally {
is.close();
}

在同樣需要進行解密。

註:(此加密有弊端)

1、加密解密演算法需保持一致。

2、加密加密密鑰需是同一密鑰。

㈡ 如何從spring官網上面下載spring-data-redis的jar包

你好請到該網址下載 ,圖中畫紅框的地址 https://mvnrepository.com

㈢ spring data jpa orderby 可以加多個參數嗎

findAllBySomeOrderOneAscTwo();

jpa多個內容排序

源碼參考:

spring-data-commmons-1.13.4


PartTree.java
L370
publicPredicate(Stringpredicate,Class<?>domainClass){
String[]parts=split(detectAndSetAllIgnoreCase(predicate),ORDER_BY);
if(parts.length>2){
("!");
}
buildTree(parts[0],domainClass);
this.orderBySource=parts.length==2?newOrderBySource(parts[1],domainClass):null;
}

OrderBySource.java
L65
publicOrderBySource(Stringclause,Class<?>domainClass){
this.orders=newArrayList<Sort.Order>();
for(Stringpart:clause.split(BLOCK_SPLIT)){//BLOCK_SPLIT="(?<=Asc|Desc)(?=\p{Lu})";
//
}
}

㈣ java Spring 的JDBCTemplet批量入庫數據時如果有一條數據入庫不成功,其他的數據還會入庫嗎

在我們的項目中遇到這樣一個問題:我們的項目需要連接多個資料庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的資料庫。我們以往在spring和hibernate框架中總是配置一個數據源,因而sessionFactory的dataSource屬性總是指向這個數據源並且恆定不變,所有DAO在使用sessionFactory的時候都是通過這個數據源訪問資料庫。但是現在,由於項目的需要,我們的DAO在訪問sessionFactory的時候都不得不在多個數據源中不斷切換,問題就出現了:如何讓sessionFactory在執行數據持久化的時候,根據客戶的需求能夠動態切換不同的數據源?我們能不能在spring的框架下通過少量修改得到解決?是否有什麼設計模式可以利用呢?問題的分析我首先想到在spring的applicationContext中配置所有的dataSource。這些dataSource可能是各種不同類型的,比如不同的資料庫:Oracle、sqlServer、MySQL等,也可能是不同的數據源:比如apache提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然後sessionFactory根據客戶的每次請求,將dataSource屬性設置成不同的數據源,以到達切換數據源的目的。但是,我很快發現一個問題:當多用戶同時並發訪問資料庫的時候會出現資源爭用的問題。這都是「單例模式」惹的禍。眾所周知,我們在使用spring框架的時候,在beanFactory中注冊的bean基本上都是採用單例模式,即spring在啟動的時候,這些bean就裝載到內存中,並且每個bean在整個項目中只存在一個對象。正因為只存在一個對象,對象的所有屬性,更准確說是實例變數,表現得就如同是個靜態變數(實際上「靜態」與「單例」往往是非常相似的兩個東西,我們常常用「靜態」來實現「單例」)。拿我們的問題來說,sessionFactory在整個項目中只有一個對象,它的實例變數dataSource也就只有一個,就如同一個靜態變數一般。如果不同的用戶都不斷地去修改dataSource的值,必然會出現多用戶爭用一個變數的問題,對系統產生隱患。通過以上的分析,解決多數據源訪問問題的關鍵,就集中在sessionFactory在執行數據持久化的時候,能夠通過某段代碼去根據客戶的需要動態切換數據源,並解決資源爭用的問題。問題的解決(一)採用Decorator設計模式要解決這個問題,我的思路鎖定在了這個dataSource上了。如果sessionFactory指向的dataSource可以根據客戶的需求去連接客戶所需要的真正的數據源,即提供動態切換數據源的功能,那麼問題就解決了。那麼我們怎麼做呢?去修改那些我們要使用的dataSource源碼嗎?這顯然不是一個好的方案,我們希望我們的修改與原dataSource代碼是分離的。根據以上的分析,使用GoF設計模式中的Decorator模式(裝飾者模式)應當是我們可以選擇的最佳方案。什麼是「Decorator模式」?簡單點兒說就是當我們需要修改原有的功能,但我們又不願直接去修改原有的代碼時,設計一個Decorator套在原有代碼外面。當我們使用Decorator的時候與原類完全一樣,當Decorator的某些功能卻已經修改為了我們需要修改的功能。Decorator模式的結構如圖。我們本來需要修改圖中所有具體的Component類的一些功能,但卻並不是去直接修改它們的代碼,而是在它們的外面增加一個Decorator。Decorator與具體的Component類都是繼承的AbstractComponent,因此它長得和具體的Component類一樣,也就是說我們在使用Decorator的時候就如同在使用ConcreteComponentA或者ConcreteComponentB一樣,甚至那些使用ConcreteComponentA或者ConcreteComponentB的客戶程序都不知道它們用的類已經改為了Decorator,但是Decorator已經對具體的Component類的部分方法進行了修改,執行這些方法的結果已經不同了。(二)設計MultiDataSource類現在回到我們的問題,我們需要對dataSource的功能進行變更,但又不希望修改dataSource中的任何代碼。我這里指的dataSource是所有實現javax.sql.DataSource介面的類,我們常用的包括apache提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等,這些類我們不可能修改它們本身,更不可能對它們一個個地修改以實現動態分配數據源的功能,同時,我們又希望使用dataSource的sessionFactory根本就感覺不到這樣的變化。Decorator模式就正是解決這個問題的設計模式。首先寫一個Decorator類,我取名叫MultiDataSource,通過它來動態切換數據源。同時在配置文件中將sessionFactory的dataSource屬性由原來的某個具體的dataSource改為MultiDataSource。如圖:對比原Decorator模式,AbstractComponent是一個抽象類,但在這里我們可以將這個抽象類用介面來代替,即DataSource介面,而ConcreteComponent就是那些DataSource的實現類,如BasicDataSource、JndiObjectFactoryBean等。MultiDataSource封裝了具體的dataSource,並實現了數據源動態切換:java代碼{privateDataSourcedataSource=null;publicMultiDataSource(DataSourcedataSource){this.dataSource=dataSource;}publicConnectiongetConnection()throwsSQLException{returngetDataSource().getConnection();}//其它DataSource介面應當實現的方法publicDataSourcegetDataSource(){returnthis.dataSource;}}publicvoidsetDataSource(DataSourcedataSource){this.dataSource=dataSource;}}客戶在發出請求的時候,將dataSourceName放到request中,然後把request中的數據源名通過調用newMultiDataSource(dataSource)時可以告訴MultiDataSource客戶需要的數據源,就可以實現動態切換數據源了。但細心的朋友會發現這在單例的情況下就是問題的,因為MultiDataSource在系統中只有一個對象,它的實例變數dataSource也只有一個,就如同一個靜態變數一般。正因為如此,單例模式讓許多設計模式都不得不需要更改,這將在我的《「單例」更改了我們的設計模式》中詳細討論。那麼,我們在單例模式下如何設計呢?(三)單例模式下的MultiDataSource在單例模式下,由於我們在每次調用MultiDataSource的方法的時候,dataSource都可能是不同的,所以我們不能將dataSource放在實例變數dataSource中,最簡單的方式就是在方法getDataSource()中增加參數,告訴MultiDataSource我到底調用的是哪個dataSource:java代碼publicDataSourcegetDataSource(StringdataSourceName){log.debug("dataSourceName:"+dataSourceName);try{if(dataSourceName==null||dataSourceName.equals("")){returnthis.dataSource;}return(DataSource)this.applicationContext.getBean(dataSourceName);}catch(){thrownewDaoException("ThereisnotthedataSource}}值得一提的是,我需要的數據源已經都在spring的配置文件中注冊,dataSourceName就是其對應的id。xml代碼oracle.jdbc.driver.OracleDrivervalue>property>bean>oracle.jdbc.driver.OracleDrivervalue>property>bean>為了得到spring的ApplicationContext,MultiDataSource類必須實現介面org.springframework.context.ApplicationContextAware,並且實現方法:java代碼=null;()throwsBeansException{this.applicationContext=applicationContext;}如此這樣,我就可以通過this.applicationContext.getBean(dataSourceName)得到dataSource了。(四)通過線程傳遞dataSourceName查看以上設計,MultiDataSource依然無法運行,因為用戶在發出請求時,他需要連接什麼資料庫,其數據源名是放在request中的,要將request中的數據源名傳給MultiDataSource,需要經過BUS和DAO,也就是說為了把數據源名傳給MultiDataSource,BUS和DAO的所有方法都要增加dataSourceName的參數,這是我們不願看到的。寫一個類,通過線程的方式跳過BUS和DAO直接傳遞給MultiDataSource是一個不錯的設計:java代碼publicclassSpObserver{privatestaticThreadLocallocal=newThreadLocal();publicstaticvoidputSp(Stringsp){local.set(sp);}publicstaticStringgetSp(){return(String)local.get();}}做一個filter,每次客戶發出請求的時候就調用SpObserver.petSp(dataSourceName),將request中的dataSourceName傳遞給SpObserver對象。最後修改MultiDataSource的方法getDataSource():java代碼publicDataSourcegetDataSource(){Stringsp=SpObserver.getSp();returngetDataSource(sp);}完整的MultiDataSource代碼在附件中。(五)動態添加數據源通過以上方案,我們解決了動態分配數據源的問題,但你可能提出疑問:方案中的數據源都是配置在spring的ApplicationContext中,如果我在程序運行過程中動態添加數據源怎麼?這確實是一個問題,而且在我們的項目中也確實遇到。spring的ApplicationContext是在項目啟動的時候載入的。載入以後,我們如何動態地載入新的bean到ApplicationContext中呢?我想到如果用spring自己的方法解決這個問題就好了。所幸的是,在查看spring的源代碼後,我找到了這樣的代碼,編寫了DynamicLoadBean類,只要調用loadBean()方法,就可以將某個或某幾個配置文件中的bean載入到ApplicationContext中(見附件)。不通過配置文件直接載入對象,在spring的源碼中也有,感興趣的朋友可以自己研究。(六)在spring中配置在完成了所有這些設計以後,我最後再嘮叨一句。我們應當在spring中做如下配置:xml代碼bean>property>bean>property>bean>其中dataSource屬性實際上更准確地說應當是defaultDataSource,即spring啟動時以及在客戶沒有指定數據源時應當指定的默認數據源。該方案的優勢以上方案與其它方案相比,它有哪些優勢呢?首先,這個方案完全是在spring的框架下解決的,數據源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource屬性,它甚至都不知道dataSource的改變。唯一不同的是在真正的dataSource與sessionFactory之間增加了一個MultiDataSource。其次,實現簡單,易於維護。這個方案雖然我說了這么多東西,其實都是分析,真正需要我們寫的代碼就只有MultiDataSource、SpObserver兩個類。MultiDataSource類真正要寫的只有getDataSource()和getDataSource(sp)兩個方法,而SpObserver類更簡單了。實現越簡單,出錯的可能就越小,維護性就越高。最後,這個方案可以使單數據源與多數據源兼容。這個方案完全不影響BUS和DAO的編寫。如果我們的項目在開始之初是單數據源的情況下開發,隨著項目的進行,需要變更為多數據源,則只需要修改spring配置,並少量修改MVC層以便在請求中寫入需要的數據源名,變更就完成了。如果我們的項目希望改回單數據源,則只需要簡單修改配置文件。這樣,為我們的項目將增加的彈性。特別說明:實例中的DynamicLoadBean在web環境下運行會出錯,需要將類中AbstractApplicationContext改為org.springframework.context.。

㈤ spring-data-redis可以設置超時時間嗎

不需要了,sdr說白了底層還是jedis的工程,你可以看下源碼,沒多少行,很簡單。不懂歡迎追問!

熱點內容
什麼叫蘋果版的和安卓版的手機 發布:2025-05-15 21:05:18 瀏覽:252
編程找點 發布:2025-05-15 20:43:10 瀏覽:587
php上傳臨時文件夾 發布:2025-05-15 20:43:00 瀏覽:657
impala資料庫 發布:2025-05-15 20:42:12 瀏覽:649
android安裝插件 發布:2025-05-15 20:41:31 瀏覽:241
神秘顧客訪問 發布:2025-05-15 20:33:39 瀏覽:298
安卓市場手機版從哪裡下載 發布:2025-05-15 20:17:28 瀏覽:815
幼兒速演算法 發布:2025-05-15 20:15:08 瀏覽:87
best把槍密碼多少 發布:2025-05-15 20:13:42 瀏覽:549
android安裝程序 發布:2025-05-15 20:13:20 瀏覽:560