通過自定義註解和java反射實現Spring-DI依賴注入
阿新 • • 發佈:2019-01-29
依賴注入的原理就是簡單說就是從頭往下遞迴生成依賴物件的,然後對引用欄位賦值最後返回。
這裡實現通過變數型別來生成相應的物件。
模擬一個使用者的註冊業務,首先是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();
}
}
輸出:成功注入物件。