基於註解方式純手寫spring-ioc
阿新 • • 發佈:2018-12-06
1.定義註解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExtService {
}
2.工具類
https://blog.csdn.net/qq_41988225/article/details/84393804
3.主要功能類
package com.wangyu.extspring.annotation; import java.lang.reflect.Field; import java.util.List; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang.StringUtils; /** * 手寫ioc註解版本 * */ public class ExtClassPathXmlApplicationContext { //掃包範圍 private String packageName; //儲存加了註解的類 private static ConcurrentHashMap<String, Object> beansMap = null; public ExtClassPathXmlApplicationContext(String packageName) throws Exception { beansMap = new ConcurrentHashMap<String, Object>(); if (StringUtils.isEmpty(packageName)) { return; } this.packageName = packageName; initBeans(); initEntryField(); } //給容器中的物件的初始化屬性 public void initEntryField() throws Exception { //遍歷所有的bean容器物件,判斷是否加了extresource註解 for (Entry<String, Object> entry : beansMap.entrySet()) { String key = entry.getKey(); Object object = entry.getValue(); attrAssion(object); } } //獲取bean public Object getBean(String beanId) throws Exception { if (StringUtils.isEmpty(beanId)) { throw new Exception("該beanid是空的"); } //從spring容器獲取bean Object object = beansMap.get(beanId); /**if (object == null) { throw new Exception("class not found "); }*/ //3.使用反射機制進行初始化 return object; } //初始化物件 public void initBeans() throws Exception { //1.使用java反射機制,獲取當前包下的所有類 List<Class<?>> classes = ClassUtil.getClasses(packageName); //2.判斷類上面是否有註解 ConcurrentHashMap<String, Object> classExisAnnotation = findClassExisAnnotation(classes); if (classExisAnnotation == null) { throw new Exception("該包的類沒有加註解"); } } public ConcurrentHashMap<String, Object> findClassExisAnnotation(List<Class<?>> classes) throws ClassNotFoundException, InstantiationException, IllegalAccessException { for (Class<?> classInfo : classes) { ExtService annotation = classInfo.getAnnotation(ExtService.class); if (annotation != null) { //類名小寫作為beanId String className = classInfo.getSimpleName(); String beanId = toLowerCaseFirstOne(className); Object newInatance = newInatance(classInfo); beansMap.put(beanId, newInatance); continue; } } return beansMap; } // 首字母轉小寫 public static String toLowerCaseFirstOne(String s) { if (Character.isLowerCase(s.charAt(0))) return s; else return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString(); } //建立物件 public Object newInatance(Class<?> classInfo) throws ClassNotFoundException, InstantiationException, IllegalAccessException { return classInfo.newInstance(); } //依賴注入原理分析 public void attrAssion(Object object) throws Exception { Class<? extends Object> classInfo = object.getClass(); //獲取屬性 Field[] declaredFields = ((Class<?>) classInfo).getDeclaredFields(); for (Field field : declaredFields) { ExtResource annotation = field.getAnnotation(ExtResource.class); if (annotation != null) { //獲取屬性名稱 String beanId = field.getName(); Object bean = getBean(beanId); if (bean != null) { //預設使用屬性名稱,查詢容器物件(當前物件,給屬性賦值 ) field.setAccessible(true); //給容器中的物件的屬性進行賦值 field.set(object, bean); } } } } }
4.測試
public class ExtTest { public static void main(String[] args) throws Exception { ExtClassPathXmlApplicationContext ext = new ExtClassPathXmlApplicationContext("com.wangyu.extspring.annotation.service"); UserService bean = (UserService) ext.getBean("userService5"); System.out.println(bean); } }