首先定義一個(gè)Annotation
package com.heyang.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PrivilegeFor{
int value() default 0;
}
其次在接口IDocService中使用這個(gè)Annotation設(shè)定執(zhí)行方法所需要的權(quán)限值:
package com.heyang.service;

import com.heyang.anno.PrivilegeFor;
import com.heyang.domain.Doc;
import com.heyang.domain.User;

/**
* DocService需要實(shí)現(xiàn)的接口
* @author 何楊(heyang78@gmail.com)
*
* @since 2008-12-30 下午05:16:17
* @version 1.00
*/
public interface IDocService{
/**
* 用戶user添加一個(gè)文檔doc
* @param doc
* @param user
*/
@PrivilegeFor(value=20)
public void add(Doc doc,User user);
/**
* 用戶user刪除一個(gè)文檔doc
* @param doc
* @param user
*/
@PrivilegeFor(60)
public void delete(Doc doc,User user);
/**
* 用戶user更新一個(gè)文檔doc
* @param doc
* @param user
*/
@PrivilegeFor(value=40)
public void update(Doc doc,User user);
}
其三,在前置通知權(quán)限控制類中通過Annotation反射API得到方法需要的權(quán)限值,再根據(jù)用戶的權(quán)限值進(jìn)行權(quán)限判定,不滿足則拋出異常,這樣權(quán)限不足的用戶將無法訪問DocService的相應(yīng)方法。
package com.heyang.service;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

import com.heyang.anno.PrivilegeFor;
import com.heyang.domain.User;
import com.heyang.exception.PrivilegeNotEnoughException;

/**
* 實(shí)現(xiàn)權(quán)限子系統(tǒng)
* @author: 何楊(heyang78@gmail.com)
* @date: 2009-1-2-下午04:19:13
*/
public class PrivilegeService implements MethodBeforeAdvice{
/**
* 在IDocService的實(shí)際方法開始前進(jìn)行前置處理--權(quán)限檢查
*/
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// 取得方法名
String mothodName=arg0.getName();
// 取得方法的標(biāo)注
PrivilegeFor privilegeFor=arg0.getAnnotation(PrivilegeFor.class);
if(privilegeFor!=null){
// 取得標(biāo)注的值(即執(zhí)行方法所需要的權(quán)限)
int value=privilegeFor.value();
// 取得用戶權(quán)限
User user=(User)arg1[1];
int userPrivilegeValue=user.getPrivilegePoint();
// 權(quán)限判斷
if(userPrivilegeValue<=value){
throw new PrivilegeNotEnoughException("用戶權(quán)限必須達(dá)到"+value+"才能執(zhí)行"+mothodName+"操作");
}
}
}
}
最后的結(jié)果和XML設(shè)置的方案是一致的。
示例執(zhí)行代碼如下:
ApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml");
IDocService docService=(IDocService)ctx.getBean("docServiceProxy");
Doc doc=new Doc("論美國(guó)次貸危機(jī)的產(chǎn)生及影響");
User user=new User("中科院經(jīng)濟(jì)所研究員郭德綱",50);
// 用戶向系統(tǒng)添加文章
try{
docService.add(doc, user);
}
catch(PrivilegeNotEnoughException ex){
System.out.println(ex.getMessage());
}
// 用戶向系統(tǒng)更新文章
try{
doc.setName("論美國(guó)次貸危機(jī)的產(chǎn)生及影響和我國(guó)應(yīng)該采取的應(yīng)對(duì)措施");
docService.update(doc, user);
}
catch(PrivilegeNotEnoughException ex){
System.out.println(ex.getMessage());
}
// 用戶從系統(tǒng)撒刪除文章
try{
docService.delete(doc, user);
}
catch(PrivilegeNotEnoughException ex){
System.out.println(ex.getMessage());
}
}
執(zhí)行效果:
將文件 名=論美國(guó)次貸危機(jī)的產(chǎn)生及影響交由dao處理(存入數(shù)據(jù)庫(kù))
將文件 名=論美國(guó)次貸危機(jī)的產(chǎn)生及影響和我國(guó)應(yīng)該采取的應(yīng)對(duì)措施交由dao處理(更新數(shù)據(jù)庫(kù)中對(duì)應(yīng)的記錄)
用戶權(quán)限必須達(dá)到60才能執(zhí)行delete操作
代碼下載:
http://www.aygfsteel.com/Files/heyang/PrivilegeAnnotation20090106155940.rar
http://www.aygfsteel.com/Files/heyang/PrivilegeAnnotation220090108213912.rar
需要自行載入的包為:
commons-logging-1.0.4.jar,log4j-1.2.14.jar,spring.jar,mysql-connector-java-5.0.6-bin.jar












其次在接口IDocService中使用這個(gè)Annotation設(shè)定執(zhí)行方法所需要的權(quán)限值:






































其三,在前置通知權(quán)限控制類中通過Annotation反射API得到方法需要的權(quán)限值,再根據(jù)用戶的權(quán)限值進(jìn)行權(quán)限判定,不滿足則拋出異常,這樣權(quán)限不足的用戶將無法訪問DocService的相應(yīng)方法。









































最后的結(jié)果和XML設(shè)置的方案是一致的。
示例執(zhí)行代碼如下:
































執(zhí)行效果:



代碼下載:
http://www.aygfsteel.com/Files/heyang/PrivilegeAnnotation20090106155940.rar
http://www.aygfsteel.com/Files/heyang/PrivilegeAnnotation220090108213912.rar
需要自行載入的包為:
commons-logging-1.0.4.jar,log4j-1.2.14.jar,spring.jar,mysql-connector-java-5.0.6-bin.jar