1. 程式人生 > >通過自定義註解和java反射實現Spring-DI依賴注入

通過自定義註解和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:這就是生成依賴物件的核心程式碼邏輯啦:主要是通過生成相應的物件然後不斷遞迴。

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();
    }


}

輸出:成功注入物件。