自定义注解注入属性值(基于类构造方法)

本文将举例说明如何通过构造方法来处理注解,实现属性注入

  1. 自定义注解Name
  2. 实现超类,定义注解处理方法
  3. 子类使用注解

自定义注解Name

定义一个注解“Name”,Name注解可以接收一个String类型的属性,并且可以使用在类或者属性上

@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Name {

    String value() default "";
}

超类实现

实现一个超类Person,并在Person的构造方法中使用Java反射机制注入属性

public abstract class Person {

    public Person() {
        setName(this.getClass());
    }

    public void setName(Class clazz) {
        //处理注解在类上
        if (clazz.isAnnotationPresent(Name.class)) {
            Name annotation = (Name) clazz.getAnnotation(Name.class);
            try {
                Field field = clazz.getDeclaredField("name");
                field.setAccessible(true);
                field.set(this, annotation.value());
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return;
        }
        //处理注解在属性上
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Name annotation = declaredField.getAnnotation(Name.class);
            if (null == annotation) {
                continue;
            }
            declaredField.setAccessible(true);
            try {
                declaredField.set(this, annotation.value());
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

子类使用自定义注解

定义类Xiaolv,并继承Person,Xiaolv类用@Name注解修饰(为name属性注入值为“小绿”)

@Name("小绿")
public class Xiaolv extends Person{
    
    private String name;

    public void sayHi() {
        System.out.println("hello, my name is " + name);
    }
}

测试一下

如下例子会打印出:
hello, my name is 小绿

@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloTest {

    @Test
    public void HelloXiaolvTest() {
        Xiaolv xiaolv = new Xiaolv();
        xiaolv.sayHi();
    }
}

子类属性使用自定义注解

定义类Xiaolan,并继承Person,Xiaolan类的属性name用@Name注解修饰(为name属性注入值为“小绿”)

public class Xiaolan extends Person{

    @Name("小蓝")
    private String name;

    public void sayHi() {
        System.out.println("hello, my name is " + name);
    }
}

测试一下

如下例子会打印出:
hello, my name is 小蓝

@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloTest {

    @Test
    public void HelloXiaolanTest() {
        Xiaolan xiaolan = new Xiaolan();
        xiaolan.sayHi();
    }
}

总结

本文举例说明了一种处理自定义注解的方式,通过类构造器在对象创建后注入属性。

在实际开发中,处理注解还有其他多种方式,各有优缺点。

例如:

  • 在Bean的后置处理器中处理注解
    通过实现Bean的后置处理器方法,配合Java反射。
    这种注解可以使用在类、方法、属性上。
    局限性是这种注解只能在Spring Bean中使用。
    参考SpringBoot之自定义注解(基于BeanPostProcessor接口实现)

  • 通过Spring AOP处理
    原理是通过注解来定义切点。
    优点是编写简单。
    但这种注解也只能使用在Spring Bean中,且只能作用于方法上
    参考SpringBoot之自定义注解(基于AOP实现)

  • 通过AspectJ切面处理
    通过SspectJ切面编程实现,类似SPring AOP切面。而已没有只能作用在方法上的局限

  • 通过Spring配置类处理
    通过配置类实现在Spring启动过程中处理注解,配置Java反射机制来注入静态变量。
    局限性是只能注入静态属性。
    参考自定义注解注入属性值(基于反射和静态变量)

博主个人博客原文

你可能感兴趣的:(java,spring,日常小笔记)