关闭

观察者设计模式实现缓存机制

标签: 设计模式缓存机制观察者
238人阅读 评论(0) 收藏 举报
本文实现的是角色的缓存实现。
1.缓存的实现接口SystemCacheServiceInterface如下:
package com.woyi.sms.cache.service.inter;

/**
 * *
 * 
 * @ClassName: SystemCacheService *
 * @Description: 系统缓存实现接口,该接口在WEB容器启动时可以自动加载缓存*
 * @author woyi *
 * @date 2010-11-22 上午10:06:22 *
 */
public interface SystemCacheServiceInterface {

	/**
	 * 第一次WEB容器启动时加载缓存运行的方法。
	 */
	void run();

}
2.系统缓存加载类SystemCache如下:
package com.woyi.sms.cache;

import java.util.List;

/**
 * *
 * 
 * @ClassName: SystemCache *
 * @Description: 系统缓存加载类 *
 * @author woyi *
 * @date 2010-11-22 上午10:04:42 *
 */
public class SystemCache {

	/**
	 * 需要在系统启动时运行的SystemCacheService实现类
	 */
	private List<String> loadClass;

	public SystemCache() {

	}

	/**
	 * 
	 * @param loadClass
	 */
	public void setLoadClass(List<String> loadClass) {
		this.loadClass = loadClass;
	}

	public List<String> getLoadClass() {
		return this.loadClass;
	}
}
3.spring配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
	default-autowire="byName">

	<bean id="configCacheObservable"
		class="com.woyi.sms.cache.observable.ConfigCacheObservable"
		factory-method="getInstance" />
	<bean id="roleCacheObservable"
		class="com.woyi.sms.cache.observable.RoleCacheObservable"
		factory-method="getInstance" />
	<bean id="deptCacheObservable"
		class="com.woyi.sms.cache.observable.DeptCacheObservable"
		factory-method="getInstance">
	</bean>

	<bean id="configCacheDao"
		class="com.woyi.sms.cache.daos.ConfigCacheDao">
		<property name="sqlMapClient" ref="sysSqlMapClient"></property>
	</bean>

	<bean id="roleCacheDao"
		class="com.woyi.sms.cache.daos.RoleCacheDao">
		<property name="sqlMapClient" ref="sysSqlMapClient"></property>
	</bean>

	<bean id="deptCacheDao"
		class="com.woyi.sms.cache.daos.DeptCacheDao">
		<property name="sqlMapClient" ref="sysSqlMapClient"></property>
	</bean>

	<bean id="systemCache" class="com.woyi.sms.cache.SystemCache">
		<property name="loadClass">
			<list>
				<value>configCacheDao</value>
				<value>roleCacheDao</value>
				<value>deptCacheDao</value>
			</list>
		</property>
	</bean>
</beans>
4.主题如下:
package com.woyi.sms.cache.observable;

import java.util.Observable;

/**
 * * @Title: CacheObservable.java
 * 
 * @Package com.woyi.phc.web.support.cache.observable * @Description: 观察者模式 *
 *          被观察者
 * @author woyi * @date 2010-11-22 下午04:10:40 * @version V1.0
 */
public class RoleCacheObservable extends Observable {

	private static RoleCacheObservable instance;

	/**
	 * 
	 * 此方法描述的是:保证单列
	 * 
	 * @author: woyi
	 * @version: 2010-11-30 上午09:29:54
	 */
	public synchronized static RoleCacheObservable getInstance() {
		if (instance == null) {
			instance = new RoleCacheObservable();
		}
		return instance;
	}

	/***
	 * 
	 * 此方法描述的是:设置改变 通知所有观察者
	 * 
	 * @author: woyi
	 * @version: 2010-12-6 上午10:38:05
	 */
	public void setCacheChanged() {
		setChanged(); // 设定改变了
		notifyObservers(); // 通知所有的观察者
	}
}
5.观察者如下
package com.woyi.sms.cache.daos;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import com.woyi.core.dao.IBatis.IBatisEntityDao;
import com.woyi.sms.cache.domain.RoleMenuUrlVo;
import com.woyi.sms.cache.observable.RoleCacheObservable;
import com.woyi.sms.cache.service.inter.SystemCacheServiceInterface;
import com.woyi.sms.security.domain.Role;

public class RoleCacheDao extends IBatisEntityDao<Role> implements
		SystemCacheServiceInterface, Observer {

	public static HashMap<Long, List<String>> roleMenuUrlCache = new HashMap<Long, List<String>>();

	public RoleCacheDao() {
		// 被观察者
		RoleCacheObservable.getInstance().addObserver(this);
	}

	public void run() {
		// TODO Auto-generated method stub
		if (logger.isInfoEnabled())
			logger.info("角色缓存初始化开始......");
		long time = System.currentTimeMillis();
		RoleCacheDao.roleMenuUrlCache.clear();
		// 获取所有的角色
		List<Role> roleList = super.getAll();
		// 获取角色菜单中间表与菜单表
		List<RoleMenuUrlVo> volist = super.getAll(RoleMenuUrlVo.class);
		List<String> list = null;
		for (Role r : roleList) {
			list = new ArrayList<String>();
			for (RoleMenuUrlVo vo : volist) {
				if (r.getId().equals(vo.getRoleId())) {
					list.add(vo.getMenuUrl());
				}
			}
			roleMenuUrlCache.put(r.getId(), list);
		}
		roleList = null;
		volist = null;
		list = null;
		time = System.currentTimeMillis() - time;
		if (logger.isInfoEnabled()) {
			logger.info("角色缓存初始化结束......" + time);
		}
		Runtime.getRuntime().gc();
	}

	public void update(Observable o, Object arg) {
		this.run();
	}

}
6.系统启动时加载缓存
/**
 * 
 */
package com.woyi.sms.cache;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.woyi.sms.cache.service.inter.SystemCacheServiceInterface;

/**
 * *
 * 
 * @ClassName: SystemStartLoad *
 * @Description: Web容器启动时加载的方法。 *
 * @author woyi *
 * @date 2010-11-22 上午10:06:43 *
 */
public class SystemStartLoad implements ServletContextListener {
	Logger logger = Logger.getLogger(getClass());

	private SystemCache systemCache;

	public SystemCache getSystemCache() {
		return systemCache;
	}

	public void setSystemCache(SystemCache systemCache) {
		this.systemCache = systemCache;
	}

	/**
	 * Web容器结束时执行的方法
	 */
	public void contextDestroyed(ServletContextEvent arg0) {
		if (logger.isInfoEnabled())
			logger.info("--> contextDestroyed(ServletContextEvent arg0)");

	}

	/**
	 * WEB容器启动时执行的方法
	 */
	public void contextInitialized(ServletContextEvent arg0) {
		if (this.logger.isInfoEnabled())
			logger.info("启动--> contextInitialized(ServletContextEvent arg0)");

		systemCache = (SystemCache) WebApplicationContextUtils
				.getWebApplicationContext(arg0.getServletContext()).getBean(
						"systemCache");
		if (systemCache.getLoadClass() != null
				&& !systemCache.getLoadClass().isEmpty()) {
			for (int i = 0; i < systemCache.getLoadClass().size(); i++) {
				SystemCacheServiceInterface scs = (SystemCacheServiceInterface) WebApplicationContextUtils
						.getWebApplicationContext(arg0.getServletContext())
						.getBean(systemCache.getLoadClass().get(i));
				scs.run();
			}
		}
		// systemCache.run();
	}

}
7.登录时使用缓存
package com.woyi.web.filter;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.woyi.core.web.Constants;
import com.woyi.core.web.util.RequestUtil;
import com.woyi.sms.cache.daos.RoleCacheDao;
import com.woyi.sms.code.CodeHandler;
import com.woyi.sms.security.domain.User;

/**
 * 一些资源需要登陆后才可以访问 过滤管理员的
 * 
 * @author woyi
 * 
 */
public class LoginFilter implements Filter {
	private String sessionOut;

	public void destroy() {

	}

	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) arg0;
		HttpServletResponse response = (HttpServletResponse) arg1;
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute(Constants.USER_CURRENT_SESSION);
		if (user == null) {
			response.sendRedirect(request.getContextPath() + "/" + sessionOut);
			return;
		} else {// 对URL进行过滤
			String url = RequestUtil.getRealUrl(request);
			// 当前角色具有的 菜单
			List<String> roleUrlList = RoleCacheDao.roleMenuUrlCache.get(user
					.getRoleId());
			// 因为默认角色具有最高权限 所以取默认角色的权限 认定为 系统所有菜单
			List<String> adminUrlList = RoleCacheDao.roleMenuUrlCache
					.get(CodeHandler.DEFAULT_ID);
			// 如果在表中定义了 那么该菜单才需要过滤
			if (adminUrlList.contains(url)) {
				// 判断 当前角色是否具有此菜单
				if (!roleUrlList.contains(url)) {
					response.sendRedirect(request.getContextPath()
							+ "/Insufficient.jsp");
					return;
				}
			}

		}
		arg2.doFilter(arg0, arg1);
	}

	public void init(FilterConfig arg0) throws ServletException {
		sessionOut = arg0.getInitParameter("sessionOut");
	}

}
8.对角色进行新增,修改,删除时要通知观察者
@RequestMapping(params = "action=doAddRole")
public void doAdd(@ModelAttribute("role")
Role role, HttpServletResponse response) {
	try {
		role.setCreateUserId(SessionUtil.getCurrentUser().getId());
		roleService.insertRole(role);
		RoleCacheObservable.getInstance().setCacheChanged();
		super.ajaxForward(response, OK);
	} catch (SQLException e) {
		logger.error("do add role throw exception : ", e);
		super.ajaxForward(response, ERROR);
	}
}









0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Cocos中的观察者设计模式与通知机制

观察者(Observer)模式也叫发布/订阅(Publish/Subscribe)模式,是 MVC( 模型-视图-控制器)模式的重要组成部分。天气一直是英国人喜欢讨论的话题,而最近几年天气的变化也成为...
  • tonny_guan
  • tonny_guan
  • 2014-11-02 22:24
  • 3585

JavaScript设计模式--观察者模式

一、定义观察者模式(发布-订阅模式):其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。 在JavaScript中,一般使用事件模型来替代传统的观察者模式...
  • ligang2585116
  • ligang2585116
  • 2015-12-20 19:22
  • 4897

设计模式之观察者模式与事件委托

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自己更新自己。         观察者结构模式图:     ...
  • wangdan199112
  • wangdan199112
  • 2014-02-16 21:36
  • 2259

Java设计模式之观察者模式

本文继续介绍23种设计模式系列。介绍的是观察者模式。
  • jason0539
  • jason0539
  • 2015-04-16 07:32
  • 29918

设计模式C++实现——观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。        观察者模式结构图如下:            ...
  • walkerkalr
  • walkerkalr
  • 2014-06-04 19:51
  • 1170

C++11实现观察者模式

C++11中的std::function可以接受函数指针、std::bind、lambda表达式等函数,可以达到很松的耦合,简直就是为事件机制设计的
  • xfgryujk
  • xfgryujk
  • 2017-04-06 21:23
  • 736

Java设计模式(观察者模式JDK自带)

JDK自带的观察者模式和我们上一节说的基本相似,也有通用的观察协议规则 Observer,这个接口中只有一个方法,就是update方法 public interface Observer { ...
  • xyjwsj
  • xyjwsj
  • 2017-02-15 16:47
  • 669

设计模式实战应用之二:观察者模式

观察者模式的定义         观察者模式是应用最普遍的设计模式之一。著名的 MVC 模式就是观察者模式的应用之一。Gof 把观察者模式归类到对象行为型模式,《设计模式:可复用面向对象软件的基础》对...
  • defonds
  • defonds
  • 2013-12-04 18:42
  • 5830

设计模式(五)观察者模式

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听莫一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们...
  • itachi85
  • itachi85
  • 2016-03-02 17:41
  • 37625

Qt信号槽与观察者模式

qt的核心机制:信号与槽和设计模式中的观察者模式很类似。 https://www.devbean.net/2012/08/qt-study-road-2-custom-signal-slot 这篇...
  • u011391629
  • u011391629
  • 2017-03-20 21:59
  • 1054
    个人资料
    • 访问:57481次
    • 积分:1196
    • 等级:
    • 排名:千里之外
    • 原创:62篇
    • 转载:15篇
    • 译文:0篇
    • 评论:1条