本文主要关注Spring IOC部分
将需要实例化的类提前交给Spring IOC容器,并且将类关联的类也实例化并且赋值给关联的类(称为依赖注入)。懒汉模式呢就是当我们需要这个类的时候才会去实现依赖注入。
这次主要看的是IOC也就是控制反转。
控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
(抄写百度百科,有关于Spring框架的IOC定义)
我们采用的是懒汉模式,就是先将扫描到的类先放进去,并不注入,等我开始取对象的时候再开始注入。
既然要保存那么我们就需要建立一个工厂来保存。我用的是注解的方式,当然如果你喜欢XML文件的方式也是可以的。
我们需要三个注解,@Component,@Autowire,@Bean。
- @Component需要实例化的类
- @Autowire写在成员的身上,需要实例化的类的关联类(八大基本类型就没必要了啊)
- @Bean这个是写在方法上面的(这个有一些复杂稍后再解释,和jar包有关)
像这样
@Component
public class OneKlass {
@Autowired
private Complex complex;
@Autowired
private MecPoint point;
写好之后让我们来建一个工厂。(BeanFactory)工厂里面有一个map叫beanPool,它的键为类的名字(String类型的),值为BeanDefinition(一个类)。
BeanDefinition里就是这些东西,还有这些成员的get和set方法。
private Class<?> klass;
private Object object;
private boolean inject;
klass是带有@Component注解的类,object是这个类的对象。inject是判断这个类是否被注入,就是说这个类里的带有@Autowire注解的成员是否被赋值(也可以说是否被实例化成一个对象)。
第一件事当然是进行包扫描了。将扫描到的带有@Component注解的类打扮一下,以这个类的名字为键,再构建一个BeanDefinition为值放入beanPool中就好了。
public class BeanFactory {
private static final Map<String, BeanDefinition> beanPool;
static {
beanPool = new HashMap<String, BeanDefinition>();
}
public BeanFactory() {
}
public void scanBeanByPackage(String packageName) {
ParameterDependance pd = new ParameterDependance();
OnReadyMethodBeanDefinition ormbd = new OnReadyMethodBeanDefinition();
new PackageScanner() {
@Override
public void dealClass(Class<?> klass) {
if(klass.isAnnotation()
|| klass.isEnum()
|| klass.isInterface()
|| klass.isPrimitive()
|| klass.isArray()
|| !klass.isAnnotationPresent(Component.class)) {
return;
}
Object object = null;
try {
object = klass.newInstance();
//构建一个BeanDefinition
BeanDefinition bd = new BeanDefinition();
bd.setKlass(klass);
bd.setObject(object);
beanPool.put(klass.getName(), bd);
} catch (Exception e) {
e.printStackTrace();
}
//这里只收集bean,并不对bean做任何处理。
collectBean(klass, object, ormbd);
}
}.packageScanner(packageName);
//这里才对bean进行处理
pd.dealDependance(ormbd);
dealOnreadyBean(ormbd, pd