Spring中的注入开始让我很迷,不清楚这个名词代表什么意思,怎么说呢,网上有一个很好的例子,就是说假如我是一个妖怪,我需要吃小孩,但是小孩不能凭空产生啊,需要有一个男人和一个女人,以及通过一个嘿嘿嘿的函数(小孩类构造函数),把这个小孩给造出来把,那么我只想去吃小孩,我不想去管它怎么来的,那么Spring的实现就相当于作为一个容器,假如我要吃小孩了,就从中拿出来吃就行了,不用去关心它是怎么来的,由Spring容器帮我们实现,
所以说,Spring中的注入,可以看做对被注入类的成员的声明以及实例化,也就是说,以后这个对象不用我们自己new,而是由Spring给我们自动完成了new,我们直接调用就好了,这是我们要解决的一个问题,如果不考虑太多细节的问题,可以说Spring就主要完成了这个,那么其中有个问题了,假如我们需要注入的类和其他类有依赖关系呢,或者这样说,有一个类A需要被注入,B,C是注入的成员,但是B又需要C去注入,C又需要A去注入,这样就出现了一个循环,就像三个人围成一个圈,两个人中间一只筷子,每个人都需要拿到两只筷子才能吃,这样就尬住了,任何一个人都不能吃饭,都要等,在程序中就会造成无限递归的问题,如何解决循环依赖,这就是我们的主要方向,先看工程的结构:
先说BeanDefinition类,这个类就是把需要被注入的类的对象,类型,封装成一个一个Bean,再通过类名-Bean的键值装到BeanFactory中,而这个BeanFactory就是我们的核心,它就处理了我之前说的操作,对被注入类中的成员进行注入 ,三个注解@Autowired注解的意思是该成员需要被注入,@component的意思该类需要被注入,@Qualifier注解是为了解决假如需要注入的成员说是一个接口类型怎么办 **,(其实还应该有一个注解是@bean注解,用来解决假如该类无法加注解怎么办,比如该类是一个jar包中的类,那么我们的解决方案就是用这个bean注解,详细问题以后再说),**下面的model层的依赖关系是: A的注入需要B ,C;B的注入需要C;C的注入需要IA类型的A;A是IA接口的实现类,B,C是一般类;
代码如下:
@Autowired
@Retention(RUNTIME)
@Target(FIELD)
public @interface Autowired {
String value() default "";
boolean singleton() default true;
}
@Component
@Retention(RUNTIME)
@Target(TYPE)
public @interface Component {
String beanName() default "";
}
@Qualifier
@Retention(RUNTIME)
@Target(FIELD)
public @interface Qualifier {
String value();
}
BeanDefinition
public class BeanDefinition {
Class<?> klass;
Object object;
boolean done;
BeanDefinition() {
this.done = false;
}
BeanDefinition(Class<?> klass) throws Exception {
this();
this.klass = klass;
this.object = klass.newInstance();
}
BeanDefinition(Object object) {
this.object = object;
this.klass = object.getClass();
}
boolean isDone() {
return done;
}
Class<?> getKlass() {
return klass;
}
void setKlass(Class<?> klass) {
this.klass = klass;
}
Object getObject() {
return object;
}
void setObject(Object object) {
this.object = object;
}
@Override
public String toString() {
return klass + " : " + object;
}
BeanFactory
package com.mec.spring.core;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.mec.spring.annotation.Autowired;
import com.mec.spring.annotation.Component;
import com.mec.spring.annotation.Qualifier;
import com.mec.util.PackageScanner;
import com.mec.util.ValueParser;
public class BeanFactory {
private static final Map<String, BeanDefinition> beanFactory; //这个Map装的是类名-Bean
private static final Map<String, String> beanIdMap; //这个Map装的是用户自定义的类名-类名
static {
beanFactory = new ConcurrentHashMap<>();
beanIdMap = new ConcurrentHashMap<>();
}
public BeanFactory() {
}
/**
* 扫描包路径下所有的类,并且将有component注解的类变成一个Bean,加入到beanFactory
* 若用户给该类定义了新的名字,就将名字-类名放入beanIdMap,再通过类名放入beanFactory
* @param pacakgeName
*/
public void initBeanFactory(String pacakgeName) {
new PackageScanner() { //这个是做出来的包扫描工具的应用(代码在前一次的文章里)
@Override
public void dealClass(Class<?> klass) {
if (klass.isPrimitive() || klass.isInterface()
|| klass.isAnnotation() || klass.isEnum()
|| !klass.isAnnotationPresent(Component.class)) {
return;
}
String klassName = klass.getName();
String beanId = klassName;
Component component = klass.getAnnotation(Component.class); //获取带@Compoonent注解的对象
String id = component.beanName(); //取得用户自定义的类名
if (id.length() > 0) {
beanId = id;
beanIdMap.put(beanId, klassName);
}
try {
beanFactory.put(klassName, new BeanDefinition(klass));
} catch (Exception e) {
e.printStackTrace();
}
}
}.scannerPackage(pacakgeName);
}
/**
* 给Bean注入,首先检测该bean是否被注入过,如果没有,取得该类以及该类的成员
* 再检测该类的成员是否有Autowired注解,如果有,取得Autowired中 value的值
* 执行setValue()方法;
* @param bean
*/
private void setBeanValue(BeanDefinition bean) throws Exception {
if (bean.isDone()) {
return;
}
bean.done = true;
Class<?> klass = bean.getKlass();
Field[] fields = klass.getDeclaredFields();
for (Field field : fields) {
if (!field.isAnnotationPresent(Autowired.class)) {
continue;
}
Autowired autowired = field.getAnnotation(Autowired.class);
String value = autowired.value();
boolean singleton = autowired.singleton();
setValue(bean, field, value.length() <= 0 ? null : value, singleton);
}
}
/**
* 通过setBeanValue()传过来的BeanDefinition,Field,value
* 来给成员赋值
* @param bd
* @param field
* @param value
*/
private void setValue(BeanDefinition bd, Field field, String value, boolean singleton) throws Exception {
//设置了value,说明为依赖关系的最后一个
if (value != null) {
setFieldWithValue(bd.getKlass(), bd.getObject(), field, value);
return;
}
//当没有设置value,说明该成员仍然是需要注入的类
//通过成员类型再加上包名就得到了对应的类名,然后去beanFactory和beanIdMap里面找对应的类
Class<?> type = field.getType();
BeanDefinition bean = getBeanDefinition(type.getName());
if (bean == null) {
//如果找不到,去找它的父类是不是某个接口
BeanDefinition[] beans = searchBeanBySuperType(type);
if (beans.length == 1) {
bean = beans[0];
}
//存在@Qualifier注解的成员才需要去找它的接口实现类,若没有直接抛出异常
//若存在的话一个实现类那么就将这个类注入,若存在多个实现类,根据@Qualifier注解中value的值来确定是哪个实现类
if (beans.length <= 0 || !field.isAnnotationPresent(Qualifier.class)) {
throw new Exception("类" + bd.getKlass() + "的成员" + field.getName() + "注入失败!");
} else {
Qualifier qualifier = field.getAnnotation(Qualifier.class);
String beanName = qualifier.value();
bean = getBeanDefinition(beanName);
if (bean == null) {
throw new Exception("类" + bd.getKlass() + "的成员" + field.getName() + "注入失败!");
}
}
}
if (!singleton) {
bean = new BeanDefinition(type);
}
if (!bean.isDone()) {
setBeanValue(bean);
}
setFieldValue(bd.getObject(), bd.getKlass(), field, bean.getObject());
}
/**
* 如果没有在beanFactory和beanidMap中找到该类
* 那么就找在beanfactory中是否有它的实现类,如果有
* 就把它的所有实现类放入一个数组,然后返回这个数组
* 那么就在这里找
* @param klass
* @return
*/
private BeanDefinition[] searchBeanBySuperType(Class<?> klass) {
List<BeanDefinition> beanList = new ArrayList<>();
for (BeanDefinition bean : beanFactory.values()) {
Class<?> beanClass = bean.getKlass();
if (klass.isAssignableFrom(beanClass)) {
beanList.add(bean);
}
}
BeanDefinition[] beans = new BeanDefinition[beanList.size()];
beanList.toArray(beans);
return beans;
}
/**
* 将String类型的value转换为该类成员类型的value
* @param klass
* @param object
* @param field
* @param value
*/
private void setFieldWithValue(Class<?> klass, Object object, Field field, String value)
throws Exception {
Class<?> type = field.getType();
Object val = ValueParser.stringToObject(type, value);
setFieldValue(object, klass, field, val);
}
/**
* 用上一步 传过来的该类以及该类的对象,成员,还有转换过类型的value
* 给该类的成员赋值
* @param object
* @param klass
* @param field
* @param val
*/
private void setFieldValue(Object object, Class<?> klass, Field field, Object val) throws Exception {
Class<?> type = field.getType();
String fieldName = field.getName();
String methodName = "set" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
try {
//假如该类中有set方法,那么就反射机制执行他的set方法赋值
Method method = klass.getDeclaredMethod(methodName, new Class<?>[] {type});
method.invoke(object, val);
} catch (Exception e) {
//假如没有,就去直接用反射机制直接赋值
field.setAccessible(true);
field.set(object, val);
}
}
/**
* 通过beanid在beanFactory中找对应的bean
* 如果没找到再去beanIdMap中找是否有对应的classname
* @param beanId
* @return
* @throws Exception
*/
private BeanDefinition getBeanDefinition(String beanId) throws Exception {
BeanDefinition bean = beanFactory.get(beanId);
if (bean == null) {
String className = beanIdMap.get(beanId);
if (className == null) {
return null;
}
bean = beanFactory.get(className);
}
return bean;
}
//下面两个方法都是提供给外部调用的,用来给某个类进行注入
@SuppressWarnings("unchecked")
public <T> T getBean(String beanId) throws Exception {
BeanDefinition bean = getBeanDefinition(beanId);
setBeanValue(bean);
return (T) bean.getObject();
}
@SuppressWarnings("unchecked")
public <T> T getBean(Class<?> klass) throws Exception {
String beanId = klass.getName();
BeanDefinition bd = beanFactory.get(beanId);
if (bd == null) {
throw new Exception("类" + klass.getName() + "不存在!");
}
setBeanValue(bd);
return (T) bd.getObject();
}
}
IA
public interface IA {
}
A
@Component
public class A implements IA {
@Autowired
private B b;
@Autowired // (singleton=false)
private C c;
public A() {
System.out.println("A被构造!");
}
public C getC() {
return c;
}
@Override
public String toString() {
return "这就是A,其中b:" + b + ", c:" + c;
}
}
B
@Component
public class B {
@Autowired
private C c;
public B() {
}
public C getC() {
return c;
}
@Override
public String toString() {
return "这就是B!";
}
}
C
@Component
public class C {
@Autowired
@Qualifier("aa")
private IA a;
public C() {
System.out.println("C被构造!");
}
@Override
public String toString() {
return "这就是C!其中的a是" + a.getClass().getSimpleName() + "类型的!";
}
}
AA
public AA() {
System.out.println("AA被构造!");
}
@Override
public String toString() {
return "AA的对象!";
}
}
Test
public class Test {
public static void main(String[] args) {
BeanFactory beanFactory = new BeanFactory();
beanFactory.initBeanFactory("com.mec.spring.test.model");
try {
A a = beanFactory.getBean(A.class);
System.out.println(a);
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
从结果可以清晰的看到A类的注入已经完成了,而且也没用出现循环依赖的无限递归,这是因为我们对每个Bean都加了一个Boolean类型的成员,用来记录该成员是否被注入过,如果被注入过,下次需要注入的时候,就直接用将该成员传过去,不用再进行注入了。