簡介
spring ioc的極簡實作,可以完成自動屬性注入,使用二級快取解決回圈依賴(就是把半成品物件放個map里先保存著),基于注解,可以指定組態檔,總計不到100行代碼,可以簡單對spring依賴注入有個大致的了解,專案下載鏈接在文末
大概步驟
最基本的注解
Autowired注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
Component注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
ComponentScan注解(這個注解其實也可以不要,比如默認就掃描main方法目錄)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {
String value();
}
Application類
用來決議組態檔,創建bean
public class Application {
Map<Class<?>,Object> singletonInstance =new HashMap<>();
Map<Class<?>,Object> earlySingletonInstance=new HashMap<>();
Set<Class<?>> classSet=new HashSet<>();
public Application(Class<?> configClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//獲得掃描路徑
String path = configClass.getDeclaredAnnotation(ComponentScan.class).value();
ClassLoader classLoader = Application.class.getClassLoader();
//獲得掃描路徑下所有檔案
for (File file : new File(classLoader.getResource(path.replace(".","/")).getFile()).listFiles()) {
//這里沒有遞回處理,只掃描第一層的class檔案
if(!file.getName().endsWith(".class"))continue;
String fullName=(path+"."+file.getName()).replace(".class","");
Class<?> aClass = classLoader.loadClass(fullName);
//保存所有被Component注解的類
if(aClass.isAnnotationPresent(Component.class))classSet.add(aClass);
}
//生成半成品物件放到二級快取
for (Class<?> aClass : classSet) earlySingletonInstance.put(aClass,aClass.newInstance());
//Autowired屬性注入
for (Class<?> aClass : classSet){
Object instance = earlySingletonInstance.get(aClass);
for (Field field : aClass.getDeclaredFields()) {
if(field.isAnnotationPresent(Autowired.class)){
field.setAccessible(true);
field.set(instance,earlySingletonInstance.get(field.getType()));
}
}
//放到單例池
singletonInstance.put(aClass, instance);
}
}
//按型別獲取,生成的都是單例bean
public <T> T getBean(Class<T> clazz){
return clazz.cast(singletonInstance.get(clazz));
}
}
測驗
Calculate.java,Service.java這兩個檔案位于io.spring.test目錄下
@Component
public class Calculate {
@Autowired
private Service service;
public int add(int x,int y){
return service.add(x, y);
}
}
@Component
public class Service {
@Autowired
Calculate calculate;//測驗回圈依賴
public int add(int x, int y) {
return x+y;
}
}
@ComponentScan("io.spring.test")//掃描路徑
public class App {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Application appContext = new Application(App.class);//初始化
Calculate cal = appContext.getBean(Calculate.class);//獲得bean物件
System.out.println(cal.add(3,5));
}
}
測驗程式輸出8,說明依賴注入的目的達到了
專案下載
https://github.com/fuchengshun/simple-spring-ioc
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/283008.html
標籤:Java
上一篇:Netty 框架學習 —— 第一個 Netty 應用
下一篇:尼科徹斯定理
