就是在方法的上面加入@Autowired註解,容器中的對象會注入到對應類型的參數。ide
注意:暫時實現注入一個對象。全部方法的參數列表的參數只能有一個。測試
其實實現的思路和給字段注入的邏輯是同樣的。遍歷類全部的方法有沒有@Autowired,有的就給它賦予容器中對應的對象。this
1. 在AbstractApplicationContext類增長兩個方法區分屬性注入(autowiredField)和方法注入(autowiredMethod)spa
1 /** 2 * 屬性注入 3 * @param object 4 * @param context 5 * @throws IllegalArgumentException 6 * @throws IllegalAccessException 7 */ 8 private void autowiredField(Object object,Context context) throws IllegalArgumentException, IllegalAccessException { 9 // 5.得到對象的表結構 10 Class<? extends Object> classType = object.getClass(); 11 // 6.得到字段的結構 12 Field[] fields = classType.getDeclaredFields(); 13 for (int i = 0; i < fields.length; i++) { 14 // autowired得到註解 15 Autowired autowired = fields[i].getAnnotation(Autowired.class); 16 if (autowired != null) { 17 Class<?> fieldType = fields[i].getType(); 18 String fieldName = fields[i].getName(); 19 // 若是容器裏面有對應的對象 20 Object fieldObject = context.getObject(fieldType, fieldName); 21 // 容許訪問私有方法 22 if (fieldObject != null) { 23 // 屬性是私有的也能夠訪問 24 fields[i].setAccessible(true); 25 // 將屬性值賦予這個對象的屬性 26 fields[i].set(object, fieldObject); 27 } 28 29 } 30 } 31 } 32 /** 33 * 注意set方法的規範 34 * 限定方法只能注入一個參數,而且注入對象的方法只能有一個參數 35 * @param object 36 * @param context 37 * @throws IllegalArgumentException 38 * @throws IllegalAccessException 39 * @throws InvocationTargetException 40 */ 41 private void autowiredMethod(Object object,Context context) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { 42 // 5.得到對象的表結構 43 Class<? extends Object> classType = object.getClass(); 44 // 6.得到類方法的結構 45 Method[] methods = classType.getDeclaredMethods(); 46 for (int i = 0; i < methods.length; i++) { 47 // autowired得到註解 48 Autowired autowired = methods[i].getAnnotation(Autowired.class); 49 if (autowired != null) { 50 //得到參數列表的類型 51 Class<?>[] parameterTypes = methods[i].getParameterTypes(); 52 53 String fieldName = methods[i].getName(); 54 55 // 若是容器裏面有對應的對象,限定一個方法只能注入一個對象 56 Object methodObject = context.getObject(parameterTypes[0], fieldName); 57 // 容許訪問私有方法 58 if (methodObject != null) { 59 // 屬性是私有的也能夠訪問 60 methods[i].setAccessible(true); 61 // 將屬性值賦予這個對象的屬性 62 methods[i].invoke(object, methodObject); 63 } 64 65 } 66 } 67 }
2.修改autowired方法的邏輯。將原來只遍歷屬性的@Autowired註解,修改成同時遍歷屬性和方法上面的的對象注入註解@Autowiredcode
/** * 給對象的屬性注入關聯的對象 * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException */ private void autowired() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { // 1.得到容器 Context context = contexts.get(); // 2.得到容器中的全部對象。 Map<String, Object> objects = context.getObjects(); // 3.得到容器中全部的對象值 Collection<Object> values = objects.values(); // 4.得到對象的迭代器 Iterator<Object> iterator = values.iterator(); while (iterator.hasNext()) { Object object = iterator.next(); //1.注入到屬性 this.autowiredField(object, context); //2.注入到方法 this.autowiredMethod(object, context); } }
測試目錄結構對象
1.在UserServiceImpl類裏面增長經過方法注入UserDAO的註解blog
1 package ioc.core.test.service.impl; 2 3 import ioc.core.annotation.Autowired; 4 import ioc.core.annotation.stereotype.Service; 5 import ioc.core.test.dao.UserDAO; 6 import ioc.core.test.service.UserService; 7 8 /** 9 * 一個普通的類,用於測試是否能夠建立對象 10 * @author ranger 11 * 12 */ 13 @Service 14 public class UserServiceImpl implements UserService { 15 16 @Autowired 17 private UserDAO userDAO; 18 19 @Override 20 public void login(){ 21 System.out.println("-登陸Service-"); 22 userDAO.save(); 23 } 24 25 }
2.測試類調用UserController的對象get
1 package ioc.core.test; 2 3 import org.junit.Test; 4 5 import ioc.core.impl.AnntationApplicationContext; 6 import ioc.core.test.config.Config; 7 import ioc.core.test.controller.UserController; 8 9 public class AnntationApplicationContextTest { 10 11 @Test 12 public void login(){ 13 try { 14 AnntationApplicationContext context=new AnntationApplicationContext(Config.class); 15 UserController userController = context.getBean("userController", UserController.class); 16 userController.login(); 17 System.out.println(context.getContext().getObjects()); 18 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 } 23 24 }
3.測試結果,同時能夠調用UserController,UserServiceImpl,UserDAO對象。說明成功!it