通过自定义注解和java反射实现Spring-DI依赖注入

依赖注入的原理就是简单说就是从头往下递归生成依赖对象的,然后对引用字段赋值最后返回。

这里实现通过变量类型来生成相应的对象。

模拟一个用户的注册业务,首先是controller层调用service层,然后调用dao层代码实现保存用户。

文件结构:

UserController

package cn.wzy.controller;

import cn.wzy.DI.Inject;
import cn.wzy.service.UserService;

/**
 * Create by Wzy
 * on 2018/8/3 14:31
 * 不短不长八字刚好
 */
public class UserController {

    @Inject
    private UserService userService;

    public void save() {
        userService.save();
    }

    public UserController() {
    }
}

UserService:模拟保存用户,更新相关班级的操作

package cn.wzy.service;

import cn.wzy.dao.ClassDao;
import cn.wzy.dao.UserDao;
import cn.wzy.DI.Inject;

/**
 * Create by Wzy
 * on 2018/8/3 14:29
 * 不短不长八字刚好
 */
public class UserService {

    @Inject
    private UserDao userDao;

    @Inject
    private ClassDao classDao;

    public void save() {
        userDao.save();
        classDao.save();
    }

    public UserService() {
    }
}

ClassDao:

package cn.wzy.dao;

/**
 * Create by Wzy
 * on 2018/8/3 14:28
 * 不短不长八字刚好
 */

public class ClassDao {


    public ClassDao() {
    }

    public void save() {
        System.out.println("------start--------");
        System.out.println("this is ClassDao...");
        System.out.println("i'm saving......");
        System.out.println("-------end---------");
    }
}

UserDao

package cn.wzy.dao;

/**
 * Create by Wzy
 * on 2018/8/3 14:24
 * 不短不长八字刚好
 */
public class UserDao {

    public UserDao() {
    }

    public void save() {
        System.out.println("------start--------");
        System.out.println("this is UserDao...");
        System.out.println("i'm saving........");
        System.out.println("-------end---------");
    }
}

自定义注解没有任何信息,就只是为了标识是否需要注入。

package cn.wzy.DI;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Create by Wzy
 * on 2018/8/3 14:25
 * 不短不长八字刚好
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Inject {

}

BeanFactory:这就是生成依赖对象的核心代码逻辑啦:主要是通过生成相应的对象然后不断递归。

扫描二维码关注公众号,回复: 2547291 查看本文章
package cn.wzy.DI;

import java.lang.reflect.Field;

/**
 * Create by Wzy
 * on 2018/8/3 14:24
 * 不短不长八字刚好
 */

public class BeanFactory {

    public static <Q> Q getBean(Class<Q> clazz) {
        Q result = null;
        try {
            result = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
            System.out.println("get the " + clazz.getName() + "failed!!");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("get the " + clazz.getName() + "failed!!");
            e.printStackTrace();
            return null;
        }
        //查找所有的字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {//查找字段中含有依赖注入的字段 存在就进行注入
            Inject inject = field.getAnnotation(Inject.class);
            if (inject != null) {
                Object object = getBean(field.getType());
                if (!field.isAccessible())
                    field.setAccessible(true);
                try {
                    field.set(result,object);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    System.out.println("Inject the " + field.getName() + "failed!!");
                }
            }
        }
        return result;
    }
}

测试:

package cn.wzy.test;

import cn.wzy.DI.BeanFactory;
import cn.wzy.controller.UserController;

/**
 * Create by Wzy
 * on 2018/8/3 14:33
 * 不短不长八字刚好
 */
public class UserControllerTest {


    public static void main(String[] args) {
        UserController userController = BeanFactory.getBean(UserController.class);
        userController.save();
    }


}

输出:成功注入对象。

猜你喜欢

转载自blog.csdn.net/qq_38089964/article/details/81387848