真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Spring緩存機(jī)制實(shí)例代碼

Spring的緩存機(jī)制非常靈活,可以對(duì)容器中任意Bean或者Bean的方法進(jìn)行緩存,因此這種緩存機(jī)制可以在JavaEE應(yīng)用的任何層次上進(jìn)行緩存。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),鄂倫春企業(yè)網(wǎng)站建設(shè),鄂倫春品牌網(wǎng)站建設(shè),網(wǎng)站定制,鄂倫春網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,鄂倫春網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

Spring緩存底層也是需要借助其他緩存工具來實(shí)現(xiàn),例如EhCache(Hibernate緩存工具),上層則以統(tǒng)一API編程。

要使用Spring緩存,需要以下三步

  • 1.向Spring配置文件導(dǎo)入context:命名空間
  • 2.在Spring配置文件啟用緩存,具體是添加
  • 3.配置緩存管理器,不同的緩存實(shí)現(xiàn)配置不同,如果是EhCache,需要先配置一個(gè)ehcache.xml

例如

<?xml version="1.0" encoding="UTF-8"?>

  
  
  
  
  

上面的ehcache.xml配置了兩個(gè)緩存區(qū),Spring中的Bean將會(huì)緩存在這些緩存區(qū)中,一般的,Spring容器中有多少個(gè)Bean,就會(huì)在ehcache中定義多少個(gè)緩存區(qū)。

接著在Spring配置文件中配置緩存管理器如下,其中第一個(gè)Bean是一個(gè)工廠Bean,用來配置EhCache的CacheManager, 第二個(gè)Bean才是為Spring緩存配置的緩存管理器,所以將第一個(gè)Bean注入第二個(gè)Bean。



  
  
  
   
  

下面是一個(gè)完整的Spring配置,

<?xml version="1.0" encoding="UTF-8"?>


  
    
  

  
  
  
   
  
  

下面將以@Cacheable為例,演示Spring基于EhCache緩存的用法。 Cacheable用于修飾類或者方法,如果修飾類,則類中所有方法都會(huì)被緩存。

類級(jí)別的緩存

例如有如下Bean類,

@Service("userService")
@Cacheable(value="users")
public class UserServiceImpl implements UserService {

  @Override
  public User getUsersByNameAndAge(String name, int age) {
    System.out.println("正在執(zhí)行g(shù)etUsersByNameAndAge()..");
    return new User(name,age);
  }

  @Override
  public User getAnotherUser(String name, int age) {
    System.out.println("正在執(zhí)行g(shù)etAnotherUser()..");
    return new User(name,age);
  }
}

基于類的緩存,將會(huì)緩存類中的所有方法,緩存之后,程序調(diào)用該類實(shí)例的任何方法,只要傳入的參數(shù)相同,Spring將不會(huì)真正執(zhí)行該方法,而是直接根據(jù)傳入的參數(shù)去查找緩存中的數(shù)據(jù)!

比如像下面這樣使用緩存數(shù)據(jù),

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    User u1 = us.getUsersByNameAndAge("張三", 50);
    //由于第二次調(diào)用userService方法時(shí),使用了相同參數(shù),那么真正的方法將不會(huì)執(zhí)行,
    //Spring將直接從緩存按參數(shù)查找數(shù)據(jù)
    User u2 = us.getAnotherUser("張三", 50);
    System.out.println(u1==u2);
  }

輸出結(jié)果,

正在執(zhí)行g(shù)etUsersByNameAndAge()..
true

可以看到,上面的getAnotherUser()并沒有真正執(zhí)行,因?yàn)閭魅氲膮?shù)與之前的方法傳入的參數(shù)相同,于是Spring直接從緩存區(qū)數(shù)據(jù)了。

上面的Bean類中的注解@Cacheable除了必選屬性value之外,還有key, condition,, unless屬性,后面三個(gè)都是用來設(shè)置Spring存儲(chǔ)策略,對(duì)于基于類的緩存來說,Spring默認(rèn)以方法傳入的參數(shù)作為key去緩存中查找結(jié)果。

當(dāng)然我們也可以修改key的策略,讓Spring按照其他標(biāo)準(zhǔn),比如按照第一個(gè)參數(shù)是否相同來作為key,在緩存中查找結(jié)果。

將上面的Bean類修改如下,

@Service("userService")
@Cacheable(value="users", key="#name")
public class UserServiceImpl implements UserService {

  @Override
  public User getUsersByNameAndAge(String name, int age) {

意味著我們傳入相同的name,Spring就不會(huì)真正執(zhí)行方法。只有name不同的時(shí)候,方法才會(huì)真正執(zhí)行,例如下面,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    User u1 = us.getUsersByNameAndAge("張三", 50);
    //將@Cacheable的key參數(shù)改為key="#name"之后,下面的方法將可以執(zhí)行。
    User u2 = us.getAnotherUser("李四", 50);
    System.out.println(u1==u2);
  }

可以看到這回getAnotherUser()方法得到執(zhí)行了,

1 正在執(zhí)行g(shù)etUsersByNameAndAge()..
2 正在執(zhí)行g(shù)etAnotherUser()..
3 false

我們也可以設(shè)置condition屬性,例如,

@Service("userService")
@Cacheable(value="users", condition="#age<100")
public class UserServiceImpl implements UserService {

  @Override
  public User getUsersByNameAndAge(String name, int age) {

那么對(duì)于下面的代碼來說,兩個(gè)方法都不會(huì)被緩存,Spring每次都是執(zhí)行真正的方法取結(jié)果,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    User u1 = us.getUsersByNameAndAge("張三", 500);
    User u2 = us.getAnotherUser("李四", 500);
    System.out.println(u1==u2);
  }

執(zhí)行結(jié)果,

正在執(zhí)行g(shù)etUsersByNameAndAge()..
正在執(zhí)行g(shù)etAnotherUser()..
false

方法級(jí)別的緩存

方法級(jí)別的緩存則只會(huì)對(duì)方法起作用了,不同的方法可以設(shè)置不用的緩存區(qū),例如下面這樣,

@Service("userService")
public class UserServiceImpl implements UserService {

  @Cacheable("users1")
  @Override
  public User getUsersByNameAndAge(String name, int age) {
    System.out.println("正在執(zhí)行g(shù)etUsersByNameAndAge()..");
    return new User(name,age);
  }

  @Cacheable("users2")
  @Override
  public User getAnotherUser(String name, int age) {
    System.out.println("正在執(zhí)行g(shù)etAnotherUser()..");
    return new User(name,age);
  }
}

使用下面的測試代碼,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    //第一次執(zhí)行方法,方法將會(huì)真正執(zhí)行并緩存
    User u1 = us.getUsersByNameAndAge("張三", 500);
    //雖然下面方法傳入相同參數(shù),但是因?yàn)檫@兩個(gè)方法在不同的緩存區(qū),所以無法使用緩存數(shù)據(jù)
    User u2 = us.getAnotherUser("張三", 500);
    System.out.println(u1==u2);
    //上面已經(jīng)緩存過,這里不會(huì)真正執(zhí)行,直接使用緩存
    User u3 = us.getAnotherUser("張三", 500);
    System.out.println(u3==u2);
  }

執(zhí)行結(jié)果,

正在執(zhí)行g(shù)etUsersByNameAndAge()..
正在執(zhí)行g(shù)etAnotherUser()..
false
true

使用@CacheEvict清除緩存

被@CacheEvict修飾的方法可以用來清除緩存,使用@CacheEvict可以指定如下屬性。

allEntries, 是否清空整個(gè)緩存區(qū)

beforeInvocation: 是否在執(zhí)行方法之前清除緩存。默認(rèn)是方法執(zhí)行成功之后才清除。

condiition以及key, 與@Cacheable中一樣的含義。

下面示范簡單用啊,

@Service("userService")
@Cacheable("users")
public class UserServiceImpl implements UserService {
	@Override
	  public User getUsersByNameAndAge(String name, int age) {
		System.out.println("正在執(zhí)行g(shù)etUsersByNameAndAge()..");
		return new User(name,age);
	}
	@Override
	  public User getAnotherUser(String name, int age) {
		System.out.println("正在執(zhí)行g(shù)etAnotherUser()..");
		return new User(name,age);
	}
	//指定根據(jù)name,age參數(shù)清楚緩存
	@CacheEvict(value="users")
	  public void evictUser(String name, int age) {
		System.out.println("--正在清空"+name+","+age+"對(duì)應(yīng)的緩存--");
	}
	//指定清除user緩存區(qū)所有緩存的數(shù)據(jù)
	@CacheEvict(value="users", allEntries=true)
	  public void evictAll() {
		System.out.println("--正在清空整個(gè)緩存--");
	}
}

下面是測試類,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    //系統(tǒng)會(huì)緩存兩個(gè)方法
    User u1 = us.getUsersByNameAndAge("張三", 500);
    User u2 = us.getAnotherUser("李四",400);
    //調(diào)用evictUser()方法清除緩沖區(qū)指定的數(shù)據(jù)
    us.evictUser("李四", 400);
    //前面清除了 李四, 400 的緩存,下面的方法返回的數(shù)據(jù)將會(huì)再次被緩存
    User u3 = us.getAnotherUser("李四", 400);
    System.out.println(us == u3);  //false
    //前面已經(jīng)緩存了 張三, 500的數(shù)據(jù),下面方法不會(huì)重新執(zhí)行,直接取緩存中的數(shù)據(jù)
    User u4 = us.getAnotherUser("張三", 500);
    System.out.println(u1==u4); //輸出true
    //清空整個(gè)緩存
    us.evictAll();
    //由于整個(gè)緩存都已經(jīng)被清空,下面的代碼都會(huì)被重新執(zhí)行
    User u5 = us.getAnotherUser("張三", 500);
    User u6 = us.getAnotherUser("李四", 400);
    System.out.println(u1==u5); //輸出false
    System.out.println(u3==u6); //輸出false
  }

執(zhí)行結(jié)果,

正在執(zhí)行g(shù)etUsersByNameAndAge()..
正在執(zhí)行g(shù)etAnotherUser()..
--正在清空李四,400對(duì)應(yīng)的緩存--
正在執(zhí)行g(shù)etAnotherUser()..
false
true
--正在清空整個(gè)緩存--
正在執(zhí)行g(shù)etAnotherUser()..
正在執(zhí)行g(shù)etAnotherUser()..
false
false

總結(jié)

以上就是本文關(guān)于Spring緩存機(jī)制實(shí)例代碼的全部內(nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!


分享標(biāo)題:Spring緩存機(jī)制實(shí)例代碼
網(wǎng)址分享:http://weahome.cn/article/jpsico.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部