浅尝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框架就实现了,不过里面有很多问题,我也不想去修改了,那么多优秀的开源框架我肯定不会用自己写的。
浅尝辄止!知道什么原理就好了!