Java 中的缓存Cache机制总结

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

缓存主要可分为二大类: 

一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;  

二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查. 

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

package lhm.hcy.guge.frameset.cache;

  

import java.util.*;

  

 //Description: 管理缓存

  

 //可扩展的功能:当chche到内存溢出时必须清除掉最早期的一些缓存对象,这就要求对每个缓存对象保存创建时间

  

public class CacheManager {

    private static HashMap cacheMap = new HashMap();

  

    //单实例构造方法

    private CacheManager() {

        super();

    }

    //获取布尔值的缓存

    public static boolean getSimpleFlag(String key){

        try{

            return (Boolean) cacheMap.get(key);

        }catch(NullPointerException e){

            return false;

        }

    }

    public static long getServerStartdt(String key){

        try {

            return (Long)cacheMap.get(key);

        catch (Exception ex) {

            return 0;

        }

    }

    //设置布尔值的缓存

    public synchronized static boolean setSimpleFlag(String key,boolean flag){

        if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖

            return false;

        }else{

            cacheMap.put(key, flag);

            return true;

        }

    }

    public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){

        if (cacheMap.get(key) == null) {

            cacheMap.put(key,serverbegrundt);

            return true;

        }else{

            return false;

        }

    }

  

  

    //得到缓存。同步静态方法

    private synchronized static Cache getCache(String key) {

        return (Cache) cacheMap.get(key);

    }

  

    //判断是否存在一个缓存

    private synchronized static boolean hasCache(String key) {

        return cacheMap.containsKey(key);

    }

  

    //清除所有缓存

    public synchronized static void clearAll() {

        cacheMap.clear();

    }

  

    //清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配

    public synchronized static void clearAll(String type) {

        Iterator i = cacheMap.entrySet().iterator();

        String key;

        ArrayList arr = new ArrayList();

        try {

            while (i.hasNext()) {

                java.util.Map.Entry entry = (java.util.Map.Entry) i.next();

                key = (String) entry.getKey();

                if (key.startsWith(type)) { //如果匹配则删除掉

                    arr.add(key);

                }

            }

            for (int k = 0; k < arr.size(); k++) {

                clearOnly(arr.get(k));

            }

        catch (Exception ex) {

            ex.printStackTrace();

        }

    }

  

    //清除指定的缓存

    public synchronized static void clearOnly(String key) {

        cacheMap.remove(key);

    }

  

    //载入缓存

    public synchronized static void putCache(String key, Cache obj) {

        cacheMap.put(key, obj);

    }

  

    //获取缓存信息

    public static Cache getCacheInfo(String key) {

  

        if (hasCache(key)) {

            Cache cache = getCache(key);

            if (cacheExpired(cache)) { //调用判断是否终止方法

                cache.setExpired(true);

            }

            return cache;

        }else

            return null;

    }

  

    //载入缓存信息

    public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) {

        Cache cache = new Cache();

        cache.setKey(key);

        cache.setTimeOut(dt + System.currentTimeMillis()); //设置多久后更新缓存

        cache.setValue(obj);

        cache.setExpired(expired); //缓存默认载入时,终止状态为FALSE

        cacheMap.put(key, cache);

    }

    //重写载入缓存信息方法

    public static void putCacheInfo(String key,Cache obj,long dt){

        Cache cache = new Cache();

        cache.setKey(key);

        cache.setTimeOut(dt+System.currentTimeMillis());

        cache.setValue(obj);

        cache.setExpired(false);

        cacheMap.put(key,cache);

    }

  

    //判断缓存是否终止

    public static boolean cacheExpired(Cache cache) {

        if (null == cache) { //传入的缓存不存在

            return false;

        }

        long nowDt = System.currentTimeMillis(); //系统当前的毫秒数

        long cacheDt = cache.getTimeOut(); //缓存内的过期毫秒数

        if (cacheDt <= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE

            return false;

        else //大于过期时间 即过期

            return true;

        }

    }

  

    //获取缓存中的大小

    public static int getCacheSize() {

        return cacheMap.size();

    }

  

    //获取指定的类型的大小

    public static int getCacheSize(String type) {

        int k = 0;

        Iterator i = cacheMap.entrySet().iterator();

        String key;

        try {

            while (i.hasNext()) {

                java.util.Map.Entry entry = (java.util.Map.Entry) i.next();

                key = (String) entry.getKey();

                if (key.indexOf(type) != -1) { //如果匹配则删除掉

                    k++;

                }

            }

        catch (Exception ex) {

            ex.printStackTrace();

        }

  

        return k;

    }

  

    //获取缓存对象中的所有键值名称

    public static ArrayList getCacheAllkey() {

        ArrayList a = new ArrayList();

        try {

            Iterator i = cacheMap.entrySet().iterator();

            while (i.hasNext()) {

                java.util.Map.Entry entry = (java.util.Map.Entry) i.next();

                a.add((String) entry.getKey());

            }

        catch (Exception ex) {} finally {

            return a;

        }

    }

  

    //获取缓存对象中指定类型 的键值名称

    public static ArrayList getCacheListkey(String type) {

        ArrayList a = new ArrayList();

        String key;

        try {

            Iterator i = cacheMap.entrySet().iterator();

            while (i.hasNext()) {

                java.util.Map.Entry entry = (java.util.Map.Entry) i.next();

                key = (String) entry.getKey();

                if (key.indexOf(type) != -1) {

                    a.add(key);

                }

            }

        catch (Exception ex) {} finally {

            return a;

        }

    }

  

}

  

  

package lhm.hcy.guge.frameset.cache;

  

public class Cache {

        private String key;//缓存ID

        private Object value;//缓存数据

        private long timeOut;//更新时间

        private boolean expired; //是否终止

        public Cache() {

                super();

        }

  

        public Cache(String key, Object value, long timeOut, boolean expired) {

                this.key = key;

                this.value = value;

                this.timeOut = timeOut;

                this.expired = expired;

        }

  

        public String getKey() {

                return key;

        }

  

        public long getTimeOut() {

                return timeOut;

        }

  

        public Object getValue() {

                return value;

        }

  

        public void setKey(String string) {

                key = string;

        }

  

        public void setTimeOut(long l) {

                timeOut = l;

        }

  

        public void setValue(Object object) {

                value = object;

        }

  

        public boolean isExpired() {

                return expired;

        }

  

        public void setExpired(boolean b) {

                expired = b;

        }

}

  

//测试类,

class Test {

    public static void main(String[] args) {

        System.out.println(CacheManager.getSimpleFlag("alksd"));

//        CacheManager.putCache("abc", new Cache());

//        CacheManager.putCache("def", new Cache());

//        CacheManager.putCache("ccc", new Cache());

//        CacheManager.clearOnly("");

//        Cache c = new Cache();

//        for (int i = 0; i < 10; i++) {

//            CacheManager.putCache("" + i, c);

//        }

//        CacheManager.putCache("aaaaaaaa", c);

//        CacheManager.putCache("abchcy;alskd", c);

//        CacheManager.putCache("cccccccc", c);

//        CacheManager.putCache("abcoqiwhcy", c);

//        System.out.println("删除前的大小:"+CacheManager.getCacheSize());

//        CacheManager.getCacheAllkey();

//        CacheManager.clearAll("aaaa");

//        System.out.println("删除后的大小:"+CacheManager.getCacheSize());

//        CacheManager.getCacheAllkey();

  

  

    }

}

spring中的redis service实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594

595

596

597

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636

637

638

639

640

641

642

643

644

645

646

647

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666

667

668

669

670

671

672

673

674

675

676

677

678

679

680

681

package com.eshore.ismp.cache.redis;

 

import java.io.UnsupportedEncodingException;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Collections;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.dao.DataAccessException;

import org.springframework.data.redis.connection.RedisConnection;

import org.springframework.data.redis.core.RedisCallback;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Service;

 

@Service

public class RedisService {

 

    private static String redisCode = "utf-8";

     

    @Autowired

    private RedisTemplate<String, String> redisTemplate;

 

    /**

     * 从指定的列表右边出队,添加到目的列表中

     *

     * @param srckey

     *            源列表

     * @param dstkey

     *             目的列表

     * @return

     */

    public String rpoppush(final String srckey, final String dstkey) {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                try {

                    return new String (connection.rPopLPush(srckey.getBytes(), dstkey.getBytes()), redisCode);

                catch (UnsupportedEncodingException e) {

                    e.printStackTrace();

                }

                return "";

            }

        });

    }

    /**

     * 获取指定列表的范围数据

     *

     * @param key

     *             列表名

     * @param start

     *             开始位置

     * @param end

     *             结束位置

     * @return

     */

    public List<String> lrange(final String key, final int start, final int end) {

        return redisTemplate.execute(new RedisCallback<List<String>>() {

            List<String> result = new ArrayList<String>();

            public List<String> doInRedis(RedisConnection connection)

                    throws DataAccessException {

                List<byte[]> bytelist= connection.lRange(key.getBytes(), start, end);

                for (byte[] b : bytelist) {

                    try {

                        result.add(new String(b, redisCode));

                    catch (UnsupportedEncodingException e) {

                        e.printStackTrace();

                    }

                }

                return result;

            }

        });

    }

    /**

     * 从队列的左边取出一条数据

     *

     * @param key

     *             列表名

     * @return

     */

    public String lpop(final String key) {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                byte[] result = connection.lPop(key.getBytes());

                if (result != null) {

                    try {

                        return new String (result , redisCode);

                    catch (UnsupportedEncodingException e) {

                        e.printStackTrace();

                    }

                }

                return "";

            }

        });

    }

     

    /**

     * 从队列的左边取出一条数据

     *

     * @param key

     *             列表名

     * @return

     */

    public List<?> lpop(final String key,final int size) {

        List<Object> list =  redisTemplate.executePipelined(new RedisCallback<List<Object>>() {

            public List<Object> doInRedis(RedisConnection connection)

                    throws DataAccessException {

                byte[] keyBytes = key.getBytes();

                for(int i =0 ; i< size; i++){

                    connection.lPop(keyBytes);

                }

                return null;

            }

        });

        list.removeAll(Collections.singleton(null));

        return list;

    }

     

    /**

     * 从列表右边添加数据

     *

     * @param key

     *            列表名

     * @param values

     *            数据

     * @return

     */

    public long rpush(final String key, final String... values) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                long result = 0;

                for (String v : values) {

                    result = connection.rPush(key.getBytes(), v.getBytes());

                }

                return result;

            }

        });

    }

     

    /**

     * 从列表右边添加数据

     *

     * @param key

     *            列表名

     * @param values

     *            数据

     * @return

     */

    public long rpush(final String key, final Collection<String> values) {

        return redisTemplate.opsForList().rightPushAll(key, values);

    }

     

    public int hmset(final String key, final Map<String,String> values) {

        try{

         redisTemplate.opsForHash().putAll(key, values);

        }catch(Exception e){

            e.printStackTrace();

            return -1;

        }

        return 0 ;

    }

    public String hget(final String key, final String field){

        Object obj =redisTemplate.opsForHash().get(key, field);

        return String.valueOf(obj);

    }

     

    public List<?> hkeys(final String key){

        return redisTemplate.execute(new RedisCallback<List<Object>>(){

            List<Object> list = new ArrayList<Object>();

            public List<Object> doInRedis(RedisConnection connection)

                    throws DataAccessException {

                Set<byte[]> sets=connection.hKeys(key.getBytes());

                if(!sets.isEmpty()){

                    for(byte[] b : sets){

                        list.add(redisTemplate.getValueSerializer().deserialize(b).toString());

                    }

                    return list;

                }

                return null;

            }

        });

    }

     

    /**

     * 删除hash表中field

     */

    public void hdel(final String key,final String field){

        redisTemplate.opsForHash().delete(key, field);

    }

    /**

     * 从列表右边添加数据,并且设置列表的存活时间

     *

     * @param key

     *            列表名

     * @param liveTime

     *            存活时间(单位 秒)

     * @param values

     *            数据

     * @return

     */

    public long rpush(final String key, final int liveTime, final String... values) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                long result = 0;

                for (String v : values) {

                    connection.rPush(key.getBytes(), v.getBytes());

                }

                if (liveTime > 0) {

                    connection.expire(key.getBytes(), liveTime);

                }  

                return result;

            }

        });

    }

    /**

     * 从队列的右边取出一条数据

     *

     * @param key

     *            列表名

     * @return

     */

    public String rpop(final String key) {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                byte[] result = connection.rPop(key.getBytes());

                if(result != null ){

                    try {

                        return new String (result, redisCode);

                    catch (UnsupportedEncodingException e) {

                        e.printStackTrace();

                    }

                }

                return "";

            }

        });

    }

    /**

     * 把一个值添加到对应列表中

     *

     * @param key

     *            列表名

     * @param index

     *             添加的位置

     * @param value

     *             数据

     * @return

     */

    public String lset(final String key, final long index, final String value) {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                connection.lSet(key.getBytes(), index, value.getBytes());

                return "success";

            }

        });

    }

    /**

     * 把所有数据添加到一个列表中

     *

     * @param key

     *            列表名

     * @param values

     *             数据

     * @return

     */

    public long lpush(String key, String... values) {

        return this.lpush(key, 0, values);

    }

    /**

     * 把所有数据添加到一个列表中,并且设置列表的存活时间

     *

     * @param key

     *            列表名

     * @param values

     *            数据

     * @param liveTime

     *            存活时间--单位(秒)

     * @return

     */

    public long lpush(final String key,final  int liveTime, final String... values) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                long result = 0;

                for (String v : values){

                    result = connection.lPush(key.getBytes(), v.getBytes());

                }

                if (liveTime > 0) {

                    connection.expire(key.getBytes(), liveTime);

                }

                return result;

            }

        });

    }

    /**

     * 返回列表的长度

     *

     * @param key

     * @return

     */

    public long llen(final String key) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.lLen(key.getBytes());

            }

        });

    }

    /**

     * 删除列表中对应值的元素

     *

     * @param key

     *            列表名

     * @param count

     *            删除多少个相同的元素

     * @param value

     *            数据

     * @return

     */

    public long lrem(final String key, final long count, final String value) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.lRem(key.getBytes(), count, value.getBytes());

            }

        });

    }

    /**

     * 通过keys批量删除

     *

     * @param key

     */

    public long del(final String... keys) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                long result = 0;

                for (String k : keys) {

                    result = connection.del(k.getBytes());

                }

                return result;

            }

        });

    }

     

    /**

     *

     * //DESC 删除单个key

     * @time: 2016年5月27日 上午9:00:36

     * @param key

     * @return

     * @throws

     */

    public long del(final String key){

        return redisTemplate.execute(new RedisCallback<Long>(){

            @Override

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.del(key.getBytes());

            }

             

        });

    }

     

     

    /**

     * 添加key value 并且设置存活时间(byte)

     *

     * @param key

     * @param value

     * @param liveTime

     */

    public void set(final byte[] key, final byte[] value, final long liveTime) {

        redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                connection.set(key, value);

                if (liveTime > 0) {

                    connection.expire(key, liveTime);

                }

                return 1L;

            }

        });

         

    }

    /**

     * 添加key value 并且设置存活时间

     *

     * @param key

     * @param value

     * @param liveTime

     *            单位秒

     */

    public void set(String key, String value, long liveTime) {

        this.set(key.getBytes(), value.getBytes(), liveTime);

         

    }

    /**

     * 添加key value

     *

     * @param key

     * @param value

     */

    public void set(String key, String value) {

        this.set(key, value, 0L);

    }

     

    /**

     * 添加key value

     *

     * @param key

     * @param value

     */

    public void setMulti(final Map<String,String> map) {

        setMulti(map,0L);

    }

     

    /**

     * 添加key value

     *

     * @param key

     * @param value

     */

    public void setMulti(final Map<String,String> map,final long liveTime) {

         redisTemplate.executePipelined(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                Set<Map.Entry<String, String >> set = map.entrySet();

                for (Entry<String, String> entry : set) {

                    connection.set(entry.getKey().getBytes(), entry.getValue().getBytes());

                    if (liveTime > 0) {

                        connection.expire(entry.getKey().getBytes(), liveTime);

                    }

                }

                return null;

            }

        });

    }

    /**

     * 添加key value (字节)(序列化)

     *

     * @param key

     * @param value

     */

    public void set(byte[] key, byte[] value) {

        this.set(key, value, 0L);

         

    }

    /**

     * 获取redis value (String)

     *

     * @param key

     * @return

     */

    public String get(final String key) {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

            byte[] result = connection.get(key.getBytes());

            if (result != null) {

                try {

                    return new String (result ,redisCode);

                catch (UnsupportedEncodingException e) {

                    e.printStackTrace();

                }  

            }

            return "";

            }

        });

    }

    /**

     * 如果key不存在添加key value 并且设置存活时间(byte),当key已经存在时,就不做任何操作

     *

     * @param key

     * @param value

     * @param liveTime

     */

    public long setnx(final byte[] key, final byte[] value, final long liveTime) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                long result = 0l;

                boolean isSuccess = connection.setNX(key, value);

                if (isSuccess) {

                    if (liveTime > 0) {

                        connection.expire(key, liveTime);

                    }

                    result = 1l;

                }

                return result;

            }

        });

    }

    /**

     * 如果key不存在添加key value 并且设置存活时间,当key已经存在时,就不做任何操作

     *

     * @param key

     * @param value

     * @param liveTime

     *            单位秒

     */

    public long setnx(String key, String value, long liveTime) {

        return this.setnx(key.getBytes(), value.getBytes(), liveTime);

         

    }

    /**

     * 如果key不存在添加key value,当key已经存在时,就不做任何操作

     *

     * @param key

     * @param value

     */

    public long setnx(String key, String value) {

        return this.setnx(key, value, 0L);

    }

    /**

     * 如果key不存在添加key value (字节)(序列化),当key已经存在时,就不做任何操作

     *

     * @param key

     * @param value

     */

    public long setnx(byte[] key, byte[] value) {

        return this.setnx(key, value, 0L);

         

    }

    /**

     * 通过正则匹配keys

     *

     * @param pattern

     * @return

     */

    public Set<String> keys(final String pattern) {

        return redisTemplate.execute(new RedisCallback<Set<String>>() {

            public Set<String> doInRedis(RedisConnection connection)

                    throws DataAccessException {

            Set<String> result = new HashSet<String>();

            Set<byte[]>   data = connection.keys(pattern.getBytes());

            for(byte[] d : data){

                try {

                    result.add(new String(d,redisCode));

                catch (UnsupportedEncodingException e) {

                    e.printStackTrace();

                }

            }

            return result;

            }

        });

    }

    /**

     * 检查key是否已经存在

     *

     * @param key

     * @return

     */

    public boolean exists(final String key) {

        return redisTemplate.execute(new RedisCallback<Boolean>() {

            public Boolean doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.exists(key.getBytes());

            }

             

        });

    }

    /**

     * 清空redis 所有数据

     *

     * @return

     */

    public String flushDB() {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                connection.flushDb();

                return "success";

            }

        });

    }

    /**

     * 查看redis里有多少数据

     */

    public long dbSize() {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.dbSize();

            }

        });

    }

    /**

     * 检查是否连接成功

     *

     * @return

     */

    public String ping() {

        return redisTemplate.execute(new RedisCallback<String>() {

            public String doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.ping();

            }

        });

    }

    /**

     * 设置key的生命周期

     *

     * @param key

     * @param seconds

     *            单位(秒)

     * @return

     */

    public boolean expire(final String key, final long seconds) {

        return redisTemplate.execute(new RedisCallback<Boolean>() {

            public Boolean doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.expire(key.getBytes(), seconds);

            }

        });

    }

    /**

     * 自增长

     *

     * @param key

     * @param length 增长步长

     * @return

     */

    public long incr (final String key){

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.incr(key.getBytes());

            }

             

        });

    }

    /**

     * 自增长

     *

     * @param key

     * @param length 增长步长

     * @return

     */

    public long incrBy (final String key, final long len){

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.incrBy(key.getBytes(), len);

            }

        });

         

    }

    /**

     * 自增长

     *

     * @param key

     * @param length 增长步长

     * @return

     */

    public double incrBy (final String key, final double len){

        return redisTemplate.execute(new RedisCallback<Double>() {

            public Double doInRedis(RedisConnection connection)

                    throws DataAccessException {

                return connection.incrBy(key.getBytes(), len);

            }

        });

    }

     

    public long eval(final String luaCommand) {

        return redisTemplate.execute(new RedisCallback<Long>() {

            public Long doInRedis(RedisConnection connection) throws DataAccessException {

                return connection.eval(luaCommand.getBytes(), null,0);

            }

        });

    }

 

}

  

缓存应用:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

package com.eshore.ismp.cache.processor;

 

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.util.StringUtils;

 

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import com.eshore.ismp.cache.redis.RedisService;

import com.eshore.ismp.common.entity.ResultInfo;

 

/**

 *

 * //DESC: 管理门户缓存接口

 * @author zzx

 * @date 2016年5月20日 上午11:50:25

 */

@Service

public class AdminWebProcessor {

    private static final Logger logger = Logger.getLogger(AdminWebProcessor.class);

    private static final String ADMINWEB_USER = "ADMINWEB_USER_";

    private static final Long LIVETIME = 60*30L;

    @Autowired

    RedisService redisService;

     

    public String put(JSONObject param){

        Long userId = param.getLong("user_id");

        String userInfo = param.getString("user_info");

        ResultInfo  rs = new ResultInfo();

        if(userId==null || StringUtils.isEmpty(userInfo)){

            logger.error("参数错误");

            rs.setResult_code(2501);

            rs.setResult_detail("参数错误");

            return JSON.toJSONString(rs);

        }

        String key = ADMINWEB_USER+userId;

        redisService.set(key , userInfo,LIVETIME);

        rs.setResult_code(0);

        rs.setResult_detail("success");

        return JSON.toJSONString(rs);

    }

     

    public String get(JSONObject param){

        Long userId = param.getLong("user_id");

        String key = ADMINWEB_USER+userId;

        ResultInfo  rs = new ResultInfo();

        String user = redisService.get(key);

        rs.setResult_code(0);

        rs.setResult_detail("success");

        rs.setResult_data(user);

        return JSON.toJSONString(rs);

    }

     

    public String delete(JSONObject param){

        Long userId = param.getLong("user_id");

        String key = ADMINWEB_USER+userId;

        ResultInfo  rs = new ResultInfo();

        long isDel = redisService.del(key);

        rs.setResult_code(0);

        rs.setResult_detail("success");

        return JSON.toJSONString(rs);

    }

 

}

 

 

 

 

 

 

 

 

 

 

Ehcache中核心类和方法

 

EhCache里面有一个CacheManager类型,它负责管理cache。Cache里面存储着Element对象,Element必须是key-value对。Cache是实际物理实现的,在内存中或者磁盘。这些组件的逻辑表示就是下面即将要讨论的类。他们的方法提供了可编程的访问方式。

 

CacheManager

负责Cache的创建、访问、移除。

 

CacheManager创建

CacheManager支持两种创建模式:单例(Singleton mode)和实例(InstanceMode)。

在2.5之前的版本中,在同一个JVM中允许存在任意数量相同名字的CacheManager。每调用new CacheManager(...)一次,就会产生一个新的CacheManager实例,而不管已经存在多少个。调用CacheManager.create(...),则返回的是已经存在的那个配置对应的单例CacheManager,如果不存在,则创建一个。

 

2.5之后的版本,不允许在同一个JVM内存在多个具有相同名字的CacheManager。创建非单例实例的CacheManager()构造函数可能会打破这一规则,但是会抛出NPE异常。如果你的代码要在同一个JVM创建多个同名的实例,请使用静态方法CacheManager.create(),总是返回对应名的CacheManager(如果已经存在),否则创建一个。

 

事实上,我们可以直接利用Spring中的EhCacheManagerFactoryBean[spring2.5.4]来帮我们完成CacheManager的创建,看看它的具体创建方式:

 

 
  1. if (this.shared) {

  2. // Shared CacheManager singleton at the VM level.

  3. if (this.configLocation != null) {

  4. this.cacheManager = CacheManager.create(this.configLocation.getInputStream());

  5. }

  6. else {

  7. this.cacheManager = CacheManager.create();

  8. }

  9. }

  10. else {

  11. // Independent CacheManager instance (the default).

  12. if (this.configLocation != null) {

  13. this.cacheManager = new CacheManager(this.configLocation.getInputStream());

  14. }

  15. else {

  16. this.cacheManager = new CacheManager();

  17. }

  18. }

  19. if (this.cacheManagerName != null) {

  20. this.cacheManager.setName(this.cacheManagerName);

  21. }



 

 

EhCache2.5.2及其以上版本的创建方法归纳如下:

  • CacheManager.newInstance(Configuration configuration) :创建一个新的CacheManager 对象或者返回已经存在的对应配置中名字的CacheManager
  • CacheManager.create():创建一个新的默认配置的单例CacheManager ,或者返回一个已经存在的单例。
  • CacheManager.create(Configuration configuration),创建一个对应传入配置文件中名字的单例CacheManager,或者返回已经存在的单例CacheManager。
  • new CacheManager(Configuration configuration),创建一个新的CacheManager,或者如果对应配置的CacheManager已经存在或配置参数为空,抛出异常。

 

在Instance Mode中,如果Cache均使用MemoryStore,则没有什么特别需要注意的。但是如果使用了DIskStore,那么每个CacheManager必须具有不同的diskStore路径。当一个新的CacheManager被创建的时候,需要检查没有别的CacheManager使用同样的DiskStore路径。如果有,就会抛出异常CacheException。如果CacheManager是集群中一部分,那么其监听端口必须唯一。

 

Singletonmode和Instance Mode可以混合使用,而不会产生冲突。

 

Ehcache

所有的cache都实现了接口Ehcache。每个cache都有名字和属性,且包含Element。

Ehcache中的cache相当于其他缓存系统中的一块缓存区域。

 

Element

Element是存放于cache中的原子单位。它有一个key、一个value以及关于访问的记录。Element被放进到cache或者从cache移除。他们也可能会由于过期被移除,这依赖于配置。

 

使用实例

下面给出了一个使用Ehcache的实际例子。

首先新建一个maven java工程,在pom.xml中添加Ehcache依赖。

 

 
  1. <!-- Ehcache -->

  2. <dependency>

  3. <groupId>net.sf.ehcache</groupId>

  4. <artifactId>ehcache</artifactId>

  5. <version>2.8.3</version>

  6. </dependency>

 

 

下面是java代码。代码实现的功能非常简单,即创建CacheManager,往里面存放一个Cache,然后往cache里面存数据和取数据,目的是展示Ehcache的基本使用。

 

 
  1. /**

  2. * XXX.com Inc.

  3. * Copyright (c) 2004-2014 All Rights Reserved.

  4. */

  5. package com.test.encache;

  6.  
  7. import net.sf.ehcache.Cache;

  8. import net.sf.ehcache.CacheManager;

  9. import net.sf.ehcache.Element;

  10.  
  11. /**

  12. *

  13. * @author XXX

  14. * @version $Id: EncacheTest.java, v 0.1 2014年8月8日 下午5:30:03 XXX Exp $

  15. */

  16. public class EncacheTest {

  17. //一些配置参数

  18. //private final static String configFileName = "ehcache.xml";

  19. //private final static int maxEntriesLocalHeap = 1000;

  20. private static CacheManager cacheManager;

  21. static String cacheName = "cache1";

  22.  
  23. public static void main(String[] args) {

  24. ehcacheSetUp();

  25.  
  26. ehcacheUse();

  27. }

  28.  
  29. private static void ehcacheSetUp() {

  30.  
  31. cacheManager = CacheManager.create();

  32.  
  33. //CacheConfiguration configuration = new CacheConfiguration(configFileName,

  34. // maxEntriesLocalHeap);

  35.  
  36. //Cache cache = new Cache(configuration);

  37. cacheManager.addCache(cacheName);

  38.  
  39. }

  40.  
  41. private static void ehcacheUse() {

  42. Cache cache1 = cacheManager.getCache(cacheName);

  43. String key = "key1";

  44. String value = "value1";

  45.  
  46. writeSomeData(cache1, key, value);

  47.  
  48. Element element = readSomeData(cache1, key, value);

  49.  
  50. System.out.println(element);

  51. }

  52.  
  53. private static void writeSomeData(Cache cache, String key, String value) {

  54. cache.put(new Element(key, value));

  55. }

  56.  
  57. private static Element readSomeData(Cache cache, String key, String value) {

  58. return cache.get(key);

  59. }

  60. }


程序输出:
 
  1. SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

  2. SLF4J: Defaulting to no-operation (NOP) logger implementation

  3. SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

  4. [ key = key1, value=value1, version=1, hitCount=1, CreationTime = 1411807398768, LastAccessTime = 1411807398771 ]

 

其中的错误信息是因为没有配置日志相关的SLF4J所致。

 

下面我们要配置日志。首先在pom.xml中添加依赖:

 

 
  1. <!-- SLF4J -->

  2. <dependency>

  3. <groupId>org.slf4j</groupId>

  4. <artifactId>slf4j-log4j12</artifactId>

  5. <version>1.6.1</version>

  6. </dependency>

然后建立log4j的配置文件log4j.properties:

 

 

 
  1. # Root logger option

  2. log4j.rootLogger=INFO, file, stdout

  3. log4j.logger.com.test.encache.EncacheTest=INFO,file

  4.  
  5. # Direct log messages to a log file

  6. log4j.appender.file=org.apache.log4j.DailyRollingFileAppender

  7. log4j.appender.file.File=C:\\logging.log

  8. log4j.appender.file.layout=org.apache.log4j.PatternLayout

  9. log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

  10.  
  11. # Direct log messages to stdout

  12. log4j.appender.stdout=org.apache.log4j.ConsoleAppender

  13. log4j.appender.stdout.Target=System.out

  14. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

  15. log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

 

 

并且将这个文件放置到工程的classpath下,在这里我建立的是用Eclipse创建的maven工程,将其放置在工程主目录下的\target\classes文件夹下。
然后在代码中添加logger的初始化代码:
private static final Logger logger = LoggerFactory.getLogger(EncacheTest.class);

然后就可以使用了:

 

logger.info("Setup ehcache");
 

 

输出:

 

 
  1. 2014-09-27 17:22:45 INFO EncacheTest:35 - Setup ehcache

  2. 2014-09-27 17:22:45 WARN ConfigurationFactory:136 - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/D:/MavenRepo/net/sf/ehcache/ehcache/2.8.3/ehcache-2.8.3.jar!/ehcache-failsafe.xml

  3. 2014-09-27 17:22:46 WARN DiskStorePathManager:162 - diskStorePath 'C:\Users\xxxx\AppData\Local\Temp' is already used by an existing CacheManager either in the same VM or in a different process.

  4. The diskStore path for this CacheManager will be set to C:\Users\xxxx\AppData\Local\Temp\ehcache_auto_created7989392067865891865diskstore.

  5. To avoid this warning consider using the CacheManager factory methods to create a singleton CacheManager or specifying a separate ehcache configuration (ehcache.xml) for each CacheManager instance.

  6. [ key = key1, value=value1, version=1, hitCount=1, CreationTime = 1411809766273, LastAccessTime = 1411809766276 ]

 

 

 

 

 

import org.springframework.cache.Cache;
import org.springframework.cache.ehcache.EhCacheCacheManager;

import com.sinosig.app.base.global.ApplicationContextListener;

public class CacheUtil {
    
    public static final String BEAN_CACHEMANAGER = "cacheManager";
    /**
     * 
     * <p>
     * Title: getCache
     * </p>
     * <p>
     * Description: 如果没有对应缓存,那么自动增加一个名字为cacheName的缓存
     * </p>
     * 
     * @param cacheName
     *            缓存名称
     * @return
     * @author weiaiguo-ghq 2016年8月23日 下午6:19:20
     */
    public static Cache getCache(String cacheName) {
        EhCacheCacheManager cacheManager = ((EhCacheCacheManager) ApplicationContextListener
                .getApplicationContext().getBean(BEAN_CACHEMANAGER));
        Cache cache = cacheManager.getCache(cacheName);
        if (cache == null) {
            net.sf.ehcache.CacheManager sfCacheManager = cacheManager
                    .getCacheManager();
            sfCacheManager.addCache(cacheName);
            cache = cacheManager.getCache(cacheName);
        }
        return cache;
    }
    
    /**
     * 
     * <p>Title: clear</p>
     * <p>Description: 清除指定名称缓存</p>
     * @param cacheName 缓存名称
     * @author weiaiguo-ghq  2016年8月29日 下午3:55:34
     */
    public static void clear(String cacheName){
        EhCacheCacheManager cacheManager = ((EhCacheCacheManager) ApplicationContextListener
                .getApplicationContext().getBean(BEAN_CACHEMANAGER));
        Cache cache = cacheManager.getCache(cacheName);
        if (cache != null) {
            cache.clear();
        }
    }
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值