给手写的破产版springmvc框架加上autowired注解

接上回书:https://blog.csdn.net/qq_34785454/article/details/84728533

上一篇里我自己碎碎念了一下,要是能有手写的autowired就好了,今天决定自己动手写了。
直接上代码:
自定义的两个注解:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowired {

	String value() default "";
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyService {

	String value() default "";
}

在servlet初始化时,带@MyService注解的类也应该实例化为bean存入map当中,这里就不贴代码了,原代码加一个判断条件的事儿。

在servlet的init方法的最后调用自动注入方法:

/**
	 * 实现自动注入
	 */
	private void doAutowired() {
		if(ioc.isEmpty()) {
			return;
		}
		
		for(Entry<String, Object> e : ioc.entrySet()) {
			Class<? extends Object> clazz = e.getValue().getClass();
			if((!clazz.isAnnotationPresent(MyController.class))&&(!clazz.isAnnotationPresent(MyService.class)))
				continue;
			
			//遍历每个类中的域
			Field[] fields = clazz.getDeclaredFields();
			for(Field f:fields) {
				Annotation[] annotations = f.getAnnotations();
				for(Annotation a : annotations) {
					if(a instanceof MyAutowired){
						String fieldName = f.getName() + "Impl";
						//搜索实例化bean进行注入
						Object o = ioc.get(fieldName);
						if(o != null) {
							try {
								//这句代码一定要加!一定要加!一定要加!不然的话controller里的成员变量如果不是public,会因为没有访问权限而无法实例化赋值,就报异常了
								f.setAccessible(true);
								f.set(e.getValue(), o);
							} catch (IllegalArgumentException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							} catch (IllegalAccessException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
						}
					}
				}
			}
		}
	}

差不多就大功告成了。
新建service接口和实现类:

public interface TestService {

	String helloWorld();
}
import com.wmx.annotation.MyService;
import com.wmx.core.service.TestService;

@MyService
public class TestServiceImpl implements TestService{

	@Override
	public String helloWorld() {
		
		return "33333aaaaa";
	}

}

controller里实现注入:

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.wmx.annotation.MyAutowired;
import com.wmx.annotation.MyController;
import com.wmx.annotation.MyRequestMapping;
import com.wmx.annotation.MyRequestParam;
import com.wmx.core.service.TestService;

@MyController
@MyRequestMapping("/test")
public class TestController {
	
	@MyAutowired
	TestService testService;
 
  @MyRequestMapping("/doTest")
   public void test1(HttpServletRequest request, HttpServletResponse response,
       @MyRequestParam("param") String param){
    System.out.println(param);
     try {
           response.getWriter().write( "doTest method success! param:"+param);
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
  
  
  @MyRequestMapping("/doTest2")
   public void test2(HttpServletRequest request, HttpServletResponse response){
       try {
           response.getWriter().println("doTest2 method success!"+testService.helloWorld());
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}

将项目部署到tomcat上,启动服务,访问

http://localhost:8080/myspringmvc/test/doTest2

得到结果:
在这里插入图片描述

这里看出是返回了testservice接口的helloworld方法的值,说明自动注入调用成功。
整个过程里踩的最大的坑就是注入的时候关于成员变量的访问权限的部分,具体可以参考代码里的注释,就是那句代码一定要加,不然注入会失败,报异常。

参考:
https://blog.csdn.net/weixin_36184484/article/details/62885811
https://bbs.csdn.net/topics/340030757

感谢大佬们

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值