关闭

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

标签: 设计模式缓存机制观察者
207人阅读 评论(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网站的观点或立场
    个人资料
    • 访问:46905次
    • 积分:1087
    • 等级:
    • 排名:千里之外
    • 原创:62篇
    • 转载:15篇
    • 译文:0篇
    • 评论:1条