本文共 6056 字,大约阅读时间需要 20 分钟。
我们要完成自动装配,那么就要有一个存放bean对象的容器,然后要有装配的注解,那么哪些类该被存到容器呢,在spring中我们使用过@Service、@Resource等,看下面的代码,你也可以做到。
来看看这是一个简单的容器接口
/** * 容器接口 * @author:rex * @create_time:2014-6-26 * @version:V1.0 */public interface Container { Object getBean(String name, BeanType beanType); Object getBean(Class type, BeanType beanType); Set getBeanNames(); Collection getBeans(); boolean hasBean(Class clazz); boolean hasBean(String name); void registBean(Class clazz); void initWired(); }
这个容器提供了基础的存取方法,分别是获取bean对象和注册、是否包含bean,还有一个初始化的方法。
接下来我们来为容器做一个基本的实现。
import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import com.biezhi.ioc.BeanType;import com.biezhi.ioc.Container;import com.biezhi.ioc.anntation.Autowired;/** * 默认的bean容器实现 * @author:rex * @create_time:2014-6-26 * @version:V1.0 */public class DefaultContainerImpl implements Container { //存放bean的容器 private final MapbeansMap = new HashMap (); public DefaultContainerImpl() { //初始化加载bean ContainerLoader c = new ContainerLoader(this); c.init(); } @Override public Object getBean(String name, BeanType beanType) { try { if(beanType == BeanType.NEW) return Class.forName(name).newInstance(); } catch (Exception e) { e.printStackTrace(); } return beansMap.get(name); } @Override public Object getBean(Class type, BeanType beanType) { try { if(beanType == BeanType.NEW) return type.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Iterator
在构造器里将扫描到的类加载到容器里,然后提供注册bean和获取bean的方法。
import java.io.File;import java.io.FileFilter;import java.util.HashSet;import java.util.Set;import com.biezhi.ioc.Container;import com.biezhi.ioc.anntation.Service;import com.biezhi.ioc.util.ClassHelper;/** * 加载容器bean * @author:rex * @create_time:2014-6-26 * @version:V1.0 */public class ContainerLoader { private Container container; public ContainerLoader(Container container) { this.container = container; } public void init(){ //加载要扫描的包,这里可以使用配置文件,我们就默认扫描所有类 Setpackages = getPackages(); for(String pack : packages){ scanPack(pack); } //初始化注入 container.initWired(); } private void scanPack(String pack){ Set > classes = ClassHelper.scanPackage(pack); for(Class clazz : classes){ // 这里我只把带有@Service注解的存进去了,你也可以存其他的或者全部 Service service = clazz.getAnnotation(Service.class); if(null != service){ //将扫描到的对象保存到容器中 container.registBean(clazz); } } } /** * 获取当前classes的包名称 * @author:rex * @return */ private Set getPackages(){ Set packages = new HashSet (); String appPath = ContainerLoader.class.getResource("/").getPath(); File classDir = new File(appPath); // 如果存在 就获取包下的所有文件 包括目录 File[] dirfiles = classDir.listFiles(new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } }); for(File f : dirfiles){ packages.add(f.getName()); } return packages; }}
这个类是加载需要的类文件。还有几个代码文件没有贴出来,想看代码的等会打包自己看。
接下来我们看看这个测试,
@Servicepublic class A { String name = "菊花"; public void say(){ System.out.println("hello, I,m rex !"); }}
@Servicepublic class B { @Autowired private A a; private String qq = "3838438"; public void hehe(){ a.say(); System.out.println("请问您是" + a.name + "吗?"); } public String getQq(){ return this.qq; }}
public class Test { public static void main(String[] args) { Container c = new DefaultContainerImpl(); c.initWired(); //System.out.println(c.getBeanNames()); B b = (B) c.getBean(B.class, BeanType.SINGLE); b.hehe(); System.out.println(b.getQq()); System.out.println("=================="); B b2 = (B) c.getBean(B.class, BeanType.NEW); b2.hehe(); }}
运行结果:
hello, I,m rex !请问您是菊花吗?3838438==================Exception in thread "main" java.lang.NullPointerException at com.biezhi.ioc.test.B.hehe(B.java:15) at com.biezhi.ioc.test.Test.main(Test.java:18)
好了,这样就基本完成了一个简单的ioc自动装配。有喜欢的朋友可以参考代码。
转载地址:http://hvtwa.baihongyu.com/