@Retention: 表示注解可以保存在哪一个时期.
保存的时期的值,封装在RetentionPolicy枚举类中:
注意:一般的,自定义的注解,使用RUNTIME.(使用反射赋予注解功能)
@Target: 表示注解可以贴在哪些位置(类,方法上,构造器上等等).
位置的常量封装在ElementType枚举类中:
ElementType.ANNOTATION_TYPE只能修饰Annotation
ElementType.CONSTRUCTOR只能修饰构造方法
ElementType.FIELD只能修饰字段(属性),包括枚举常量
ElementType.LOCAL_VARIABLE只能修饰局部变量
ElementType.METHOD只能修饰方法
ElementType.PACKAGE只能修饰包(极少使用)
ElementType.PARAMETER只能修饰参数
ElementType.TYPE只能修饰类,接口,枚举
@Target(ElementType.TYPE) //表明贴的位置:类/接口/枚举
@Retention(RetentionPolicy.RUNTIME) //存在的时期
public @interface 注解名 {
String value();//抽象方法,在注解中,我们称之为属性,属性使用名词表示
int age() default 19;//设置默认值
}
注意:数据类型只能是:only primitive type(基本数据类型), String, Class, annotation, enumeration(枚举), arrays(一维数组)
使用注解:
@注解名词,但是只能贴在类/接口/枚举上.
因为注解可以贴在类,构造器,方法,字段等上.
所有在Class,Constructor,Field,Method类中,有获取注解的方法:
public boolean isAnnotationPresent(Class annotationClass):
判断该成员上是否有指定的注解标注.
public Annotation getAnnotation(Class annotationClass):
获取该成员上的指定的注解.
public Annotation[] getAnnotations():
获取该成员上所有的注解.
实例: 获取所有方法上的自定义注解,并以一定格式拼接
自定义注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {
String value();
}
@Component
public class PermissionServiceImpl implements IPermissionService{
@RequiredPermission("主键删除")
public int deleteByPrimaryKey(Long id) {
return 1;
}
@RequiredPermission("新增")
public int insert(Permission record) {
return 1;
}
@RequiredPermission("主键查询")
public Permission selectByPrimaryKey(Long id) {
return null;
}
public List<Permission> selectAll() {
return null;
}
@RequiredPermission("更新")
public int update(Permission record) {
return 1;
}
public class Permission {
private String name;
private String expression;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public Permission() {
super();
}
@Override
public String toString() {
return "Permission [name=" + name + ", expression=" + expression + "]";
}
}
public static void main(String[] args) throws Exception {
Class<?> clz = Class.forName("com.xinyi.wms.promission.PermissionServiceImpl");
Method[] methods = clz.getDeclaredMethods();
for (Method method : methods) {
RequiredPermission rp = method.getAnnotation(RequiredPermission.class);
if(rp!=null){
Permission permission = new Permission();
permission.setName(rp.value());
permission.setExpression(PermissionUtil.buildExpression(method));
System.out.println(JSON.toJSONString(permission));
}
}
}
转换格式为 —> 方法权限定名:方法名
public static String buildExpression(Method method){
String clsName = method.getDeclaringClass().getName();
String methodName = method.getName();
return clsName + ":" + methodName;
}
打印格式:
{"expression":"com.xinyi.wms.promission.PermissionServiceImpl:insert","name":"新增"}
{"expression":"com.xinyi.wms.promission.PermissionServiceImpl:deleteByPrimaryKey","name":"主键删除"}
{"expression":"com.xinyi.wms.promission.PermissionServiceImpl:selectByPrimaryKey","name":"主键查询"}
{"expression":"com.xinyi.wms.promission.PermissionServiceImpl:updateByPrimaryKey","name":"更新"}
总结:
以上方法可以用来区分操作的权限,
如把公有的东西封装到父类中(BaseController),然后子类去继承;
//获取所有同类型的Bean
使用BeanFatory的getBeansOfType()方法,该方法返回一个Map类型的实例,Map中的key为Bean的名,key对应的内容为Bean的实例。
getBeansOfType(Class),获取某一类的所有的bean。
getBeansOfType(Class,boolean,boolean),后面两个布尔值,第一代表是否也包含原型(Class祖先)bean或者或者只是singletons(包含FactoryBean生成的),第二个表示是否立即实例化懒加载或者由FactoryBean生成的Bean以保证依赖关系。
//获取继承BaseController所有的Bean
Map<String, BaseController> beanMap = SpringUtil.getApplicationContext()
.getBeansOfType(BaseController.class);
//获取所有的Controller对象
Collection<BaseController> values = beanMap.values();
//2.遍历每一个bean
for (BaseController bc: values) {
//3.获取所有的方法
Method[] methods = bc.getClass().getDeclaredMethods();
//4.获取method上的注解
for (Method method : methods) {
RequiredPermission rp = method.getAnnotation(RequiredPermission.class);
if(rp!=null){
Permission p= new Permission();
p.setName(rp.value());
p.setExpression(PermissionUtil.buildExpression(method));
System.out.println("保存permission对象到数据库");
}
}
}