springboot自定义注解(二)
程序员文章站
2022-05-23 18:28:53
...
在springboot自定义注解(一)中,我们已经用AOP实现了自定义注解的简单日志功能,今天我们来使用自定义注解实现bean的实例化。
第一步:自定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({MyBeanDefinitionRegistrar.class})
public @interface MyFirstAnnotation {
String name() default "";
int age() default 0;
}
对比springboot自定义注解(一)中的自定义注解,可以发现多了@Import({MyBeanDefinitionRegistrar.class})
,我们可以先将其理解为对注解进行处理的类,当然了,我们这里的处理就是利用注解进行bean的实例化。
第二步: 注解处理类
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MyFirstAnnotation.class.getName()));
String name = attributes.getString("name");
int age = attributes.getNumber("age");
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(Person.class);
beanDefinition.getPropertyValues().add("name", name);
beanDefinition.getPropertyValues().add("age", age);
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, "person");
BeanDefinitionReaderUtils.registerBeanDefinition(holder,registry);
}
}
其实这个类的作用很单纯,我们可以理解其功能就是可以根据注解参数来注册BeanDefinition
,该类实现了ImportBeanDefinitionRegistrar
接口,该接口只有一个方法:
/*Interface to be implemented by types that register additional bean definitions when processing @{@link Configuration} classes.*/
public interface ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
}
通过@Import
引入接口ImportBeanDefinitionRegistrar
的实现类MyBeanDefinitionRegistrar
之后,registerBeanDefinitions
方法会被调用,在该方法中我们读取到注解参数,并用这些参数的值注册了一个BeanDefinition
,spring会将所有的BeanDefinition
进行实例化,我们这里实例化了一个Person对象,它有name和age两个属性。
第三步:自定义注解的使用
@MyFirstAnnotation(name = "ty", age = 26)
public class MyController {
@Resource
private Person person;
@RequestMapping(value = "/say")
public String sayHello() {
return person.toString();
}
}
附上Person类代码:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "name=" + name + " " + "age" + " " + age;
}
}
输出结果:
name=ty age=26
尽管我们没有显示地配置person bean,但是在spring容器中还是存在它的实例,这就是我们利用自定义注解实现bean的实例化的结果。