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的理解。
实践是检验真理的惟一标准。只有咱们本身多敲代码多测试才能加深咱们对程序的理解。