1、IOC定義java
控制反轉(Inversion of Control,英文縮寫爲IoC)。程序員
定義很難理解,下面說下我我的的理解:ide
一、控制,即對象建立的控制,Java是面向對象的語言,傳統的建立對象都是手動new一個對象,是由程序員本身控制的。測試
二、反轉則是把建立對象的過程交給容器去建立。this
2、思路對象
既然是把建立對象交給容器去建立,那麼首先咱們必需要知道咱們對哪些類建立對象交給容器去管理。ip
因此就有如下類:ci
①、自定義IOC註解,只有註解的才能被容器管理get
②、要被容器管理的對象那些類源碼
③、容器類,管理對象
④、容器工廠類
⑤、建立對象的類,把建立好的對象交給容器管理
⑥、掃描類,只有被掃描到的類才能被容器管理
⑦、測試類
3、源碼實現
一、註解Ioc類
import java.lang.annotation.*; /** * @Author: liudq * @Description: 自定義IOC註解 * @Date: create in 2017/10/29 14:22 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE}) public @interface Ioc { boolean isCreate() default true; }
二、被管理對象的類
①、學生類
/** * @Author: liudq * @Description: 學生 * @Date: create in 2017/10/29 14:22 */ @Ioc public class Student<T> { private long id; private String name; private int age; private boolean sex; @Ioc private Address address; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isSex() { return sex; } public void setSex(boolean sex) { this.sex = sex; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
②、地址類
/** * @Author: liudq * @Description: 地址類 * @Date: create in 2017/10/29 14:22 */ @Ioc public class Address { private long id; @Ioc private Province province; @Ioc private City city; private String detail; public long getId() { return id; } public void setId(long id) { this.id = id; } public Province getProvince() { return province; } public void setProvince(Province province) { this.province = province; } public City getCity() { return city; } public void setCity(City city) { this.city = city; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } }
③、省類
/** * @Author: liudq * @Description: 省 * @Date: create in 2017/10/29 14:22 */ @Ioc public class Province { private long id; private String name; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
④、市類
/** * @Author: liudq * @Description: 市 * @Date: create in 2017/10/29 14:22 */ @Ioc public class City { private long id; private String name; @Ioc private Province province; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Province getProvince() { return province; } public void setProvince(Province province) { this.province = province; } }
三、容器類
/** * @Author: liudq * @Description: Bean容器 * @Date: create in 2017/10/29 14:22 */ public interface BeanContext { <T> T getBean(String name) throws Exception; <T> T getBean(Class<T> clz); <T> void addBean(Class<T> clz); void addBean(String clz); }
import java.util.HashMap; import java.util.Map; /** * @Author: liudq * @Description: 默認Bean容器類 * @Date: create in 2017/10/29 14:22 */ public class DefaultBeanContext implements BeanContext { private Map context = new HashMap(); private Bean instance = new Bean(); @Override public<T> T getBean(String name) { name = analysisName(name); return (T) context.get(name); } @Override public <T> T getBean(Class<T> clz) { return getBean(clz.getName()); } @Override public <T> void addBean(Class<T> clz) { addBean(clz.getName()); } @Override public void addBean(String name) { String key = analysisName(name); Object bean = context.get(key); if (bean == null){ bean = instance.createObject(name); context.put(key,bean); } } public static String analysisName(String name){ if (name == null || "".equals(name)){ throw new NullPointerException("類名稱不能爲空!"); } String[] split = name.split("\\."); if (split != null && split.length > 0){ String s = split[split.length - 1]; String first = s.substring(0,1).toLowerCase(); String end = s.substring(1,s.length()); return first+end; } String first = name.substring(0,1).toLowerCase(); String end = name.substring(1,name.length()); return first+end; } }
四、容器工廠類
/** * @Author: liudq * @Description: Bean容器工廠類 * @Date: create in 2017/10/29 14:22 */ public class BeanContextFactory { private static BeanContext beanContext = new DefaultBeanContext(); public static BeanContext createBeanContext(){ return beanContext; } }
五、建立對象的類
import java.lang.reflect.Constructor; import java.util.*; /** * @Author: liudq * @Description: 建立bean * @Date: create in 2017/10/29 14:22 */ public class Bean { public <T> T createObject(Class<T> clz){ return createObject(clz,null,null); } public <T> T createObject(Class<T> clz, List<Class<?>> constructTypes, List<Object> constructArgs){ Class<?> aClass = resolveInterface(clz); return (T)instance(aClass, constructTypes, constructArgs); } public Object createObject(String name) { Object o = null; try { Class<?> aClass = Class.forName(name); o = aClass.newInstance(); } catch (Exception e) { e.printStackTrace(); } return o; } protected <T> T instance(Class<T> clz, List<Class<?>> constructTypes, List constructArgs) { try { Constructor<T> constructor; if (constructTypes == null || constructArgs == null){ constructor = clz.getDeclaredConstructor(); return constructor.newInstance(); } constructor = clz.getDeclaredConstructor(constructTypes.toArray(new Class[constructArgs.size()])); return constructor.newInstance(constructArgs.toArray(new Object[constructArgs.size()])); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("建立對象異常"); } } protected Class<?> resolveInterface(Class<?> type) { Class<?> classToCreate; if (type == List.class || type == Collection.class || type == Iterable.class) { classToCreate = ArrayList.class; } else if (type == Map.class) { classToCreate = HashMap.class; } else if (type == SortedSet.class) { classToCreate = TreeSet.class; } else if (type == Set.class) { classToCreate = HashSet.class; } else { classToCreate = type; } return classToCreate; } }
六、掃描類
import java.lang.reflect.Field; /** * @Author: liudq * @Description: 掃描Bean * @Date: create in 2017/10/29 14:22 */ public class Scan { private BeanContext beanContext; public Scan(BeanContext beanContext){ this.beanContext = beanContext; } public BeanContext getBeanContext() { return beanContext; } public void setBeanContext(BeanContext beanContext) { this.beanContext = beanContext; } public void scan(Class<?> clz ){ scan(new Class[]{clz}); } public void scan(Class<?>[] clzs){ for (Class clz : clzs){ Ioc ioc = (Ioc) clz.getAnnotation(Ioc.class); if (ioc != null){ if (ioc.isCreate()){ beanContext.addBean(clz); System.out.println("類"+clz.getName()+" 被註冊"); } } Field[] declaredFields = clz.getDeclaredFields(); if (declaredFields != null){ for (Field field : declaredFields){ Ioc annotation = field.getAnnotation(Ioc.class); if (annotation != null){ if (annotation.isCreate()){ Class<?> fieldType = field.getType(); beanContext.addBean(fieldType); System.out.println(clz.getName()+"裏的"+field.getName()+"字段的類型"+fieldType.getName()+" 被註冊"); try { field.setAccessible(true); field.set(beanContext.getBean(clz),beanContext.getBean(fieldType)); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } } } }
七、測試類
/** * @Author: liudq * @Description: 測試 * @Date: create in 2017/10/29 14:22 */ public class App { public static void main(String[] args) { BeanContext beanContext = BeanContextFactory.createBeanContext(); Scan scan = new Scan(beanContext); scan.scan(new Class[]{Student.class,Address.class,Province.class,City.class}); Student student = beanContext.getBean(Student.class); System.out.println(student.getAddress().getProvince().getName()); } }
4、目的
IOC的主要目的是解耦合。
5、淺談
這裏只是一個簡單的IOC的實現,主要技術是Java的反射。但願有助於你們對IOC的理解。
實踐是檢驗真理的惟一標準。只有咱們本身多敲代碼多測試才能加深咱們對程序的理解。