浅尝系列(一)--IOC原理演示

浅尝IOC

依赖注入不过就是在一个类需要调用另一个类的方法,在类构建的时候通过java反射将另一个类传给他

简单注入

先创建一个接口


public interface Person {

	void say();
}

创建接口实现类


public class Student implements Person{

	@Override
	public void say() {
		System.out.println("逃寝通宵!!!");
		
	}

}

创建一个主类


public class Work {

	/**
	 * 需要注入接口的实现类
	 */
	private Person p;
	
	/**
	 * 通过set方法注入
	 * @param p
	 */
	public void setP(Person p) {
		this.p = p;
	}
	
	/**
	 * 执行Person的say方法
	 */
	public void say() {
		p.say();
	}
}

接下来将Student注入到Work中


import java.lang.reflect.Method;

public class Demo1 {
    
	public static void main(String[] args) throws Exception {
		//先初始化一个work的对象
		Class<?> c=Work.class;
		Object obj=c.newInstance();
		Method m=c.getDeclaredMethod("setP",Person.class);
		m.invoke(obj, Student.class.newInstance());
		Work w=(Work) obj;
		w.say();
	}
}

查看结果

逃寝通宵!!!

运行被注入的Student的say方法

通过配置注入

根据上面的代码,添加一个bean类用于保存配置


import java.util.ArrayList;
import java.util.List;

/**
 * 配置bean基础组件
 * @author dylan
 *
 */
public class Bean {

	public Bean() {}
	
	public Bean(String name,Class<?> c) {
		this.c=c;
		this.name=name;
	}
	
	private String name;
	private Class<?> c;//要被注入的对象
	
	private List<Bean> params=new ArrayList<Bean>();

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setParams(List<Bean> params) {
		this.params = params;
	}

	public void setC(Class<?> c) {
		this.c = c;
	}

	public void add(Bean bean) {
		params.add(bean);
	}

	public Class<?> getC() {
		return c;
	}

	public List<Bean> getParams() {
		return params;
	}
}

新建一个示例类


import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Demo2 {
	
	/**
	 * 配置列表
	 */
	public static Map<String, Bean> beanList=new HashMap<String, Bean>();

	/**
	 * 添加配置
	 * @param name
	 * @param bean
	 */
	public void add(String name,Bean bean) {
		beanList.put(name, bean);
	}
	
	/**
	 * 获取bean对象
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public Object getBean(String name) throws Exception {
		Bean b=beanList.get(name);
		Class<?> c=b.getC();
		Object obj=c.newInstance();
		List<Bean> bs=b.getParams();
		//检查内容并注入
		for(Bean tmp:bs) {
			Method m=c.getMethod("set"+toUpperCaseFirstOne(tmp.getName()), c.getDeclaredField(tmp.getName()).getType());
			m.invoke(obj, tmp.getC().newInstance());
		}
		return obj;
	}
	
	//首字母转小写
    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 static String toUpperCaseFirstOne(String s){
        if(Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }
    
    
	public static void main(String[] args) throws Exception {
		//初始化配置
		Bean b=new Bean();
		b.setC(Work.class);
		b.add(new Bean("p",Student.class));
		Demo2 d=new Demo2();
		d.add("work", b);
		
		Work w=(Work) d.getBean("work");
		w.say();
	}
}

这里面我直接在class中添加配置,Spring中是通过xml文件添加配置我为了少写些代码就简化了。

查看结果

逃寝通宵!!!

运行被注入的Student的say方法

多重注入

上面的方法只支持单层注入,大部分时候我们的程序都是多层调用的,所以注入也是多层的。

多层注入的话只需要在获取bean的时候加入递归方法循环一下即可。


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Demo3 {
	
	/**
	 * 配置列表
	 */
	public static Map<String, Bean> beanList=new HashMap<String, Bean>();

	/**
	 * 添加配置
	 * @param name
	 * @param bean
	 */
	public void add(String name,Bean bean) {
		beanList.put(name, bean);
	}
	
	/**
	 * 获取bean对象
	 * @param name
	 * @return
	 * @throws Exception
	 */
	public Object getBean(String name) throws Exception {
		Bean b=beanList.get(name);
		Class<?> c=b.getC();
		Object obj=c.newInstance();
		List<Bean> bs=b.getParams();
		if(bs.size()==0) {
			return obj;
		}
		//检查内容并注入
		for(Bean tmp:bs) {
			Method m=c.getMethod("set"+toUpperCaseFirstOne(tmp.getName()), c.getDeclaredField(tmp.getName()).getType());
			//继续调用函数进行下一次注入
			if(beanList.get(tmp.getName())==null) {
				m.invoke(obj, tmp.getC().newInstance());
			}else {
				m.invoke(obj, getBean(tmp.getName()));
			}
		}
		return obj;
	}
	
	private Object injection(Class<?> c) {
		Object obj=null;
			
		return obj;
	}
	
	//首字母转小写
    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 static String toUpperCaseFirstOne(String s){
        if(Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }
    
    
	public static void main(String[] args) throws Exception {
		//初始化配置
		Bean b=new Bean();
		b.setC(Work.class);
		Bean p=new Bean("p",Student.class);
		Bean w=new Bean("w",Worker.class);
		b.add(p);
		p.add(w);
		
		Demo3 d=new Demo3();
		d.add("work", b);
		d.add("p", p);
		d.add("w", w);
		
		Work work=(Work) d.getBean("work");
		work.say();
	}
}

查看结果


逃寝通宵!!!
拒绝搬砖!!!

这样一来一个简单的IOC框架就实现了,不过里面有很多问题,我也不想去修改了,那么多优秀的开源框架我肯定不会用自己写的。

浅尝辄止!知道什么原理就好了!

转载于:https://my.oschina.net/flnqs/blog/3026675

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值