Autowired注解

spring项目中我们经常使用到spring的一个注解@Autowired,这个注解是用于实现spring的特性,IOC(Inversion of Control)控制反转和DI依赖注入,spring将项目中的实体进行集中管理,然后通过@Autowired注解作为标识,以自动注入的方式来给实体注入属性,这些操作都是基于java反射机制来实现的。

因为前段时间学习了反射的一些知识,遂尝试使用反射知识来简单实现@Autowired的注入功能。

自定义注入注解@CustomAutowired

用于标识需要被注入的属性

import java.lang.annotation.*;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomAutowired {
}

User

需要被注入的类,User有个私有属性name

public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 Company

被注入User实例对象的Company

public class Company {

    @CustomAutowired
    private User user;

    public void getUserName(){
        System.out.println(user.getName());
    }
}

 MainTest

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class MainTest {

    public static void main(String[] args) {
        try {
            //获取Company的Class
            Class companyClass = Company.class;

            //新建compant对象实例
            Object company = companyClass.newInstance();
            //获取Company中所有的字段
            Field[] fields = companyClass.getDeclaredFields();

            //开始循环
            for (int i = 0; i < fields.length; i++) {
                //获取字段
                Field tempField = fields[i];
                //获取字段上的注解
                Annotation[] annotations = tempField.getAnnotations();
                //循环注解
                for (int j = 0; j < annotations.length; j++) {
                    //获取字段上注解的类型
                    Class tempAnnotationClass = annotations[j].annotationType();
                    //判断如果注解的类型是自定义的注入注解
                    if(tempAnnotationClass == CustomAutowired.class){
                        //获取字段的类型
                        Class fieldClass = tempField.getType();
                        //新建字段的实例对象
                        Object fieldObject = fieldClass.newInstance();
                        //如果字段类型是我新建的User的类型的话
                        if(fieldClass == User.class){
                            //获取User类中的name属性字段
                            Field nameField = fieldClass.getDeclaredField("name");
                            //因为User里的name字段是private的,所以要先设置访问权限为true
                            nameField.setAccessible(true);
                            //然后再给name字段设值
                            nameField.set(fieldObject,"呆某人");

                            //Company中的User字段也是private,所以也需要设置权限
                            tempField.setAccessible(true);
                            //最后给company实例对象中的user字段赋值
                            tempField.set(company,fieldObject);
                        }
                    }
                }
            }

            //获取Company中的所有方法
            Method[] methods = companyClass.getMethods();
            //开始循环
            for (int i = 0; i < methods.length; i++) {
               //找到方法名是getUserName的方法
               if("getUserName".equals(methods[i].getName())){
                   //进行调用
                   methods[i].invoke(company,null);
               }
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

首先获取到Company类对象,然后创建Company对象实例,然后获取到Company中的字段数组,开始循环字段数组,如果该字段上有@CustomAutowired注解,则实例化该字段,如果该字段是User类的话,获取它的name字段,然后给name字段赋值,再将实例化后的User对象赋值给Company对象中的User字段,这样就达到了属性注入的效果。最后循环Company中的方法,调用getUserName方法,输出结果。这就是我通过反射机制来简单实现的注入的功能。

 运行结果

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值