介绍
所谓的依赖注入本质就是控制反转,就像是本来我要什么我就去拿什么,主角是我,是我控制自己去拿我需要的工具,现在为了避免高耦合控制发生反转,我需要什么就有人帮我送过来,从此过上衣来伸手饭来张口的生活
思路
1,首先通过对项目类的class文件进行扫描,构建bean仓库
2,调用及注入,当类被调用时及进行注入
3,通过拦截自定义的注入标签,获取需要注入的类的信息,在bean仓库中,获取需要注入的类的信息,进行实例化后注入所需类
实现
1首先写一个需要作为拦截的注入标签类似spring的 @Autowired
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Injection {
public String name() default "";
}
2,当请求发生时,进行所需依赖的注入
//通过类名反射实例化对应的请求类
Class c = Class.forName(className);
//对类进行实例化
Object class1=c.newInstance();
//进行依赖注入
Field[] field = c.getDeclaredFields();
//如果该类存在属性,则对属性进行遍历扫描
if(field != null){
for(Field fie : field){
//如果该属性上有注入注解,则对该属性进行注入
if(fie.isAnnotationPresent(Injection.class)){
String InjectclassName="";
// 取消语言访问检查
fie.setAccessible(true);
//获取注解信息,及需要注入类的信息
Injection injection=fie.getAnnotation(Injection.class);
String MName= injection.name();
//从bean仓库中获取需要注入类信息
actionMap = (Map<String, Object>) SummerBeanCreat.beanMap.get(MName);
if(actionMap!=null&&actionMap.size()>0){
for (Entry<String, Object> map : actionMap.entrySet()) {
//获取类名
InjectclassName = map.getKey();
}
//通过类名获取需要注入的类的实例
Class class2 = Class.forName(InjectclassName);
Object Injectobj = class2.newInstance();
//注入
fie.set(class1 , Injectobj);
}
}
}
}
3写个测试类进行测试
接受请求类
@Action(address="testaction")
public class testAction {
@Injection(name="testaction2")
public testAction2 test2 ;
@Mapper(address="testmethod")
public void testmethod(Map map){
testAction2 testAction2=new testAction2();
System.out.println("通过实例调用");
testAction2.test1method();
System.out.println("testmethod被调用,参数是="+map.get("param2"));
System.out.println("通过注入调用");
test2.test1method();
}
@Mapper(address="test1method")
public void test1method(){
System.out.println("test1method被调用");
}
@Mapper(address="test3method")
public void test3method(){
System.out.println("test3method被调用");
}
}
被注入类
@Action(address="testaction2")
public class testAction2 {
@Mapper(address="注解testmethod21")
public void testmethod(){
}
@Mapper(address="注解test1method22")
public void test1method(){
System.out.println("testAction2,test1method被调用");
}
@Mapper(address="注解test3method23")
public void test3method(){
}
}
4效果