Springboot自定义注解

本文详细介绍了如何在SpringBoot项目中自定义@Autowired注解,实现依赖注入,并结合AOP切面编程对注解进行增强,展示了自定义注解在实际开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.项目结构

在这里插入图片描述

2.pom配置

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>

    </dependencies>

3.自定义@Autowired

1.MyAutowired

@Target(value = {ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) //该注解保持到运行期
public @interface MyAutowired {

}

2.AMyBean

/***
 *  测试是否成功注入
 */
public class TestAu {

    public static void main(String[] args) {
        BMyBean bMyBean = new BMyBean() ;
        //手动注入
        MyReflect.setObjByFieldAnno(bMyBean);
        bMyBean.la();
    }
}

3.BMyBean

public class BMyBean {
    @MyAutowired
    public AMyBean a ;  //注入AMyBean
    //使用AMyBean的方法
    public void la(){
        System.out.println(a.adds(1,20));
    }
}

4.MyReflect

public class MyReflect {

    //传入对象
    public static boolean setObjByFieldAnno(Object o){
        //获取类
        Class c = o.getClass();
        //获取域
        Field[] fields = c.getDeclaredFields();
        //用于判断这个方法是否完成
        boolean b = false;
        //便利域
        for (Field field : fields) {
            //获取域中的注解
            Annotation[] annotations = field.getAnnotations();
            //遍历注解
            for (Annotation annotation : annotations) {
                if (annotation instanceof MyAutowired){
                    //字段的类型
                    String typeName = field.getGenericType().getTypeName();
                    //字段的名称
                    String name = field.getName();
                    //获取这个字段的class
                    Class genericClass = (Class)field.getGenericType();
                    System.out.println("genericClass = " + genericClass);
//                    Class<?> type = field.getType();  //可以直接获取type
//                    String typeName1 = field.getGenericType().getTypeName();   //获取的只是类型的名称
//                    System.out.println("typeName1 = " + typeName1);
                    try {
                        //创建实例
                        Object instance = genericClass.newInstance();
                        //将这个对象注入到这个域中-----查看API
                        field.set(o,instance);
                        System.err.println("成功注入");
                        b = true;
                        return b;
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
        return b;
    }
}

5.测试 TestAu

/***
 *  测试是否成功注入
 */
public class TestAu {

    public static void main(String[] args) {
        BMyBean bMyBean = new BMyBean() ;
        //手动注入
        MyReflect.setObjByFieldAnno(bMyBean);
        bMyBean.la();
    }
}

6.打印
在这里插入图片描述

4.使用AOP切注解

1.Clc

@Target(value = {ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Clc {

    String value();
    String name() default "";

}

2.ClcAop

@Aspect
@Component
public class ClcAop {
    @Pointcut("@annotation(com.lmh.selflog.anno.Clc)")
    public void auditAspect(){
        System.out.println("Pointcut---------Pointcut---------Pointcut---------Pointcut");
    }

    //通知
    @Before("auditAspect()")
    public void doBefore(JoinPoint joinPoint){
        System.out.println("触发到 @Before(\"auditAspect()\")");
    }

    //后置通知
    @AfterReturning("auditAspect()")
    public void doAfterReturning(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println("触发 @AfterReturning(\"auditAspect()\")");
        System.out.println(args.length);
        getControllerMethodDescription(joinPoint);
    }

    /**
     * 获取注解中对方法的描述信息
     *
     * @param joinPoint 切点
     * @return 方法描述
     */
    public static void getControllerMethodDescription(JoinPoint joinPoint) {
        String targetName = joinPoint.getTarget().getClass().getName();    //获得执行方法的类名
        String methodName = joinPoint.getSignature().getName();            //获得执行方法的方法名
        Object[] arguments = joinPoint.getArgs();                          //获取切点方法的所有参数类型
        try {
            Class targetClass = Class.forName(targetName);

            Method[] methods = targetClass.getMethods();    //获取公共方法,不包括类私有的
            String value = "";
            String name = "";
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();     //对比方法中参数的个数
                    if (clazzs.length == arguments.length) {
                        value = method.getAnnotation(Clc.class).value();
                        name = method.getAnnotation(Clc.class).name();
                        break;
                    }
                }
            }
            System.out.println("value=" + value);
            System.out.println("name=" + name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.ModelController

@RestController
public class ModelController {
    @Clc(value = "clc", name = "name")
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index() {
        return "success";
    }
}

4.访问localhost:8080/index
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值