Spring启动后获取所有拥有特定注解的Bean,注解的属性值

更新时间:2023-06-21 02:34:47 阅读: 评论:0

Spring启动后获取所有拥有特定注解的Bean,注解的属性值最近项⽬中遇到⼀个业务场景,就是在Spring容器启动后获取所有的Bean中实现了⼀个特定接⼝的对象,第⼀个想到的是ApplicationContextAware,在tApplicationContext中去通过ctx获取所有的bean,后来发现好像逻辑不对,这个⽅法不是在所有bean初始化完成后实现的,后来试了⼀下看看有没有什么Listener之类的,发现了好东西ApplicationListener,然后百度⼀下ApplicationListener⽤法,原来有⼀⼤堆例⼦,我也记录⼀下我的例⼦好了。
很简单,只要实现ApplicationListener<ContextRefreshedEvent>接⼝,然后把实现类进⾏@Component即可,代码如下:
Java代码
1. <span >@Component
2. public class ContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
3.
4.    @Override
5.    public void onApplicationEvent(ContextRefreshedEvent event) {
赏月6.        // 根容器为Spring容器
7.        ApplicationContext().getParent()==null){
8.            Map<String,Object> beans = ApplicationContext().getBeansWithAnnotation(IMobile.class);
9.            for(Object bean:beans.values()){
10.                println(bean==null?"null":Class().getName());
11.            }
12.            println("=====ContextRefreshedEvent====="+Source().getClass().getName());
13.        }
14.    }
15. }</span>
其中,通过ApplicationContext().getBeansWithAnnotation获取到所有拥有特定注解的Beans集合,然后遍历所有bean实现业务场景。
总结思考:这样的功能可以实现系统参数的初始化,获取系统中所有接⼝服务清单等⼀系列需要在Spring启动后初始化的功能。
延⽣⼀下:除了以上启动后事件外,还有其他三个事件
Clod在关闭容器的时候调⽤,
Started理论上在容器启动的时候调⽤,必须增强
Stopped理论上在容器关闭的时候调⽤。
我通过TomcatServer进⾏启动停⽌,只看到了Refreshed和Clod,不知道为啥,有空再继续研究
spring中如何获取注⼊bean⾥⽅法上的注解?
有这样⼀个需求,在spring中,想⽤反射获取⼀个注⼊bean中⽅法的注解
⼀般情况下这样的操作就⾏了:
Method method = Class().getMethod(...);
Annotation[] annotations = Annotations();
这样就能获取注解了。
spring中如何获取bean的成员变量上的注解?
package com.vweb.util;
import com.vweb.webapp.Mou;
import com.vweb.webapp.MyAnno;
import com.vweb.webapp.TestUtil;
import java.lang.annotation.Annotation;
import flect.Field;
import java.util.Arrays;
import java.util.List;
public class IntactCheckUtil {
public static boolean check(Object obj){
// list = Arrays.asList(ClassLoader().loadClass(((Class)obj).getClass().getName()).getDeclaredFields());        List<Field>  list = Arrays.Class().getDeclaredFields());喝水胃疼
for(int i=0;i<list.size();i++){
Field field = (i);
红烧鸭子的家常做法视频
if(field.isAnnotationPrent(MyAnno.class)){//是否使⽤MyAnno注解
for (Annotation anno : DeclaredAnnotations()) {//获得所有的注解
if(anno.annotationType().equals(MyAnno.class) ){//找到⾃⼰的注解班级对联
if(!((MyAnno)anno).isCanNull()){//注解的值
Name(),obj)==null){
throw new RuntimeException("类:"+Mou.class+"的属性:"+Name()+"不能为空,实际的
值:"+Name(),obj)+",注解:DeclaredAnnotations()");
}
}
if(!((MyAnno)anno).isCanEmpty()){
Name(),obj).equals("")){
throw new RuntimeException("类:"+Mou.class+"的属性:"+Name()+"不能为空字符串,实际的
值:"+Name(),obj)+",注解:DeclaredAnnotations()");
}
}
if(!((MyAnno)anno).isCanZero()){
Name(),obj).toString().equals("0") ||
throw new RuntimeException("类:"+Mou.class+"的属性:"+Name()+"不能为空字符0,实际的
值:"+Name(),obj)+",注解:DeclaredAnnotations()");
}
}
}
}
}
}
return  true;
}
}
java 反射得到属性与属性值
/**
* 得到属性值
* @param obj
*/
public static void readAttributeValue(Object obj){
从容反义词
String nameVlues="";
//得到class
Class cls = Class();
//得到所有属性
Field[] fields = DeclaredFields();
for (int i=0;i<fields.length;i++){//遍历
try {
//得到属性
Field field = fields[i];虚拟网卡
//打开私有访问
field.tAccessible(true);
/
/获取属性
String name = Name();
//获取属性值
Object value = (obj);
//⼀个个赋值
nameVlues += Name()+":"+value+",";
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}       //获取最后⼀个逗号的位置       int lastIndex = nameVlues.lastIndexOf(",");   
//不要最后⼀个逗号","
String  result= nameVlues.substring(0,lastIndex);
System.out.println(result);
}
@Target:
   @Target说明了Annotation所修饰的对象范围:Annotation可被⽤于 packages、types(类、接⼝、枚举、Annotation类型)、类型成员(⽅法、构造⽅法、成员变量、枚举值)、⽅法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使⽤了target可更加明晰其修饰的⽬标。
取值(ElementType)有:
    1.CONSTRUCTOR:⽤于描述构造器
    2.FIELD:⽤于描述域
    3.LOCAL_VARIABLE:⽤于描述局部变量
    4.METHOD:⽤于描述⽅法
    5.PACKAGE:⽤于描述包
    6.PARAMETER:⽤于描述参数
    7.TYPE:⽤于描述类、接⼝(包括注解类型) 或enum声明
@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,⽽被编译器丢弃;⽽另⼀些却被编译在class⽂件中;编译在class⽂件中的Annotation可能会被虚拟机忽略,⽽另⼀些在class被装载时将被读取(请注意并不影响class的执⾏,因为Annotation与class在使⽤上是被分离的)。使⽤这个meta-Annotation可以对 Annotation的“⽣命周期”限制。
  取值(RetentionPoicy)有:
    1.SOURCE:在源⽂件中有效(即源⽂件保留)
    2.CLASS:在class⽂件中有效(即class保留)
    3.RUNTIME:在运⾏时有效(即运⾏时保留)
 @Documented:
  该属性⽤于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的⼯具⽂档化。Documented是⼀个标记注解,没有成员。
@Inherited:
  @Inherited 元注解是⼀个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果⼀个使⽤了@Inherited修饰的annotation类型被⽤于⼀个class,则这个annotation将被⽤于该class的⼦类。
  注意:@Inherited annotation类型是被标注过的class的⼦类所继承。类并不从它所实现的接⼝继承annotation,⽅法并不从它所重载的⽅法继承annotation。
  当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使⽤flect去查询⼀个@Inherited annotation类型的annotation时,反射代码检查将展开⼯作:检查class和其⽗类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
⾃定义注解:
  使⽤@interface⾃定义注解时,⾃动继承了java.lang.annotation.Annotation接⼝,由编译程序⾃动完成其他细节。在定义注解时,不能继承其他的注解或接⼝。@interface⽤来声明⼀个注解,其中的每⼀个⽅法实际上是声明了⼀个配置参数。⽅法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
  定义注解格式:
  public @interface 注解名 {定义体}
  注解参数的可⽀持数据类型:
    1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
    2.String类型
海贼王女帝图片
    3.Class类型
    4.enum类型
    5.Annotation类型
    6.以上所有类型的数组
  Annotation类型⾥⾯的参数该怎么设定:
  第⼀,只能⽤public或默认(default)这两个访问权修饰.例如,String value();这⾥把⽅法设为defaul默认类型;   
  第⼆,参数成员只能⽤基本类型byte,short,char,int,long,float,double,boolean⼋种基本数据类型和 String,Enum,Class,annotations 等数据类型,以及这⼀些类型的数组.例如,String value();这⾥的参数成员就为String; 
  第三,如果只有⼀个参数成员,最好把参数名称设为"value",后加⼩括号.例:下⾯的例⼦FruitName注解就只有⼀个参数成员。

本文发布于:2023-06-21 02:34:47,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1002780.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:类型   注解   参数   成员   获取   属性
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图