手写spring框架

在这里插入图片描述
POJO

package writeSpring.spring.beans.pojo;

public class User {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}
	
}

4个注解

package writeSpring.spring.beans.annotation;

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)
public @interface Autowired {

}




package writeSpring.spring.beans.annotation;

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)
public @interface Controllor {

}
package writeSpring.spring.beans.annotation;

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)
public @interface Repository {

}

package writeSpring.spring.beans.annotation;

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)
public @interface Service {

}

Dao层

package writeSpring.spring.beans.dao;

import java.util.ArrayList;
import java.util.List;

import writeSpring.spring.beans.annotation.Repository;
import writeSpring.spring.beans.pojo.User;


@Repository
public class UserDao {
	//模拟数据库,提供方法
	public User selectOne() {
		User u=new User();
		u.setId(1);
		u.setName("lihua");
		return u;
		
	}
	public List<User> selectAll(){
		List<User> users=new ArrayList<User>();
		//循环创建对象模拟多个数据
		for(int i=0;i<3;i++) {
			User u1=new User();
			u1.setId(10+i);
			u1.setName("伞兵"+i+"号");
			users.add(u1);
			
		}
		return users;
		
	}
	

}

service层


package writeSpring.spring.beans.service;

import java.util.List;

import writeSpring.spring.beans.annotation.Autowired;
import writeSpring.spring.beans.annotation.Service;
import writeSpring.spring.beans.dao.UserDao;
import writeSpring.spring.beans.pojo.User;


@Service
public class UserService {
	@Autowired
	private UserDao userDao;
	
	public User getone() {
		
		User u=userDao.selectOne();
		
		return u;
	}
	public List<User> getAll(){
		
		List<User> uAll=userDao.selectAll();
		
		return uAll;
	}
}

Controller层

package writeSpring.spring.beans.controllor;

import java.util.List;

import writeSpring.spring.beans.annotation.Autowired;
import writeSpring.spring.beans.annotation.Controllor;
import writeSpring.spring.beans.pojo.User;
import writeSpring.spring.beans.service.UserService;
@Controllor
public class UserControllor {
	@Autowired
	private UserService userService;
	public User getone() {
		User u=userService.getone();
		return u;
	}
	public List<User> getAll() {
		List<User> uAll=userService.getAll();
		return uAll;
	}
}

工具类

package writeSpring.spring.beans.units;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Units {
	// 传入初始路径,递归扫描获取路径下所有class文件
	public static List<String> pageScan(String Dir, List<String> list) {
		// list集合定义在方法中递归的时候会重新创建,最终只能得到一个值
		File f = new File(Dir);
		File[] listf = f.listFiles();
		for (File fi : listf) {
			if (fi.isDirectory()) {
				String str = fi.toString();
				pageScan(str, list);
			} else {
				list.add(fi.toString());
			}
		}
		return list;
	}

	// 传入bin路径和集合classList转化为formName参数,className为空集合,用于接收处理后的字符串
	public static List<String> getclassName(String baseDir,
		List<String> classList, List<String> className) {
		baseDir = baseDir.replace("\\", "/");
		for (String s : classList) {
			s = s.replace("\\", "/");
			String Dir = s.substring(baseDir.length());
			int pos = Dir.lastIndexOf(".");
			Dir = Dir.substring(0, pos);
			Dir = Dir.replace("/", ".");
			className.add(Dir);
		}
		return className;

	}
	//类名转化
	public static String getBeanName(String className) {
		
		 int t=className.lastIndexOf(".")+1;
		 String c=className.substring(t);
		 String x=c.toLowerCase();
		 className=x.charAt(0)+c.substring(1);
		
		return className;
		
	}
	
}

ComponentScan类

package writeSpring.spring.beans.parse;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import writeSpring.spring.beans.annotation.Autowired;
import writeSpring.spring.beans.annotation.Controllor;
import writeSpring.spring.beans.annotation.Repository;
import writeSpring.spring.beans.annotation.Service;
import writeSpring.spring.beans.units.Units;


public class ComponentScan {
	private static final Map<String, Object> Beans = new HashMap<String, Object>();

	// 包扫描
	public List<String> Scan(String Dir) {
		List<String> list = new ArrayList<String>();
		// 调用工具类包扫描方法
		Units.pageScan(Dir, list);
		return list;

	}
	
	public List<String> getclassName(String baseDir, List<String> classList) {
		
		List<String> className = new ArrayList<String>();
		//三个参数,baseDir是bin目录,classList是类路径集合,className是我们最终要的forName
		Units.getclassName(baseDir, classList, className);

		return className;

	}
	//根据类上是否有注解,创建对象,Ioc核心
	public void getBean(List<String> className) throws Exception {
		for (String s : className) {
			//传入className,即forName的参数,也是全局限定名,得到对应的类
			Class<?> clazz = Class.forName(s);
			//获得类上的注解
			Controllor co = clazz.getDeclaredAnnotation(Controllor.class);
			Service se = clazz.getDeclaredAnnotation(Service.class);
			Repository re = clazz.getDeclaredAnnotation(Repository.class);
			if (co != null || se != null || re != null) {
				//如果注解不为空,创建对象
				Object obj = clazz.newInstance();
				// 调用工具类转化为标准类名
				String BeanName = Units.getBeanName(s);
				//注入容器BeanName为对象名,obj为对象
				Beans.put(BeanName, obj);

			}

		}
		
	}
	//设置一个获取对象的方法
	public <T> T getObject(String BeanName) {

		return (T) Beans.get(BeanName);

	}

	public void DO() throws Exception {
		for (String BeanName : Beans.keySet()) {
			//获得容器中的对象
			Object o = getObject(BeanName);
			//获得对应对象的类
			Class<?> clazz = o.getClass();
			//获得容器中的所有属性
			Field[] fields = clazz.getDeclaredFields();
			//遍历所有属性
			for (Field f : fields) {
				//打开权限
				f.setAccessible(true);
				//获得属性上的注解,如果有的化
				Autowired au = f.getAnnotation(Autowired.class);
				
				if (au != null) {
					//有对应注解的属性,获得属性名如:userController
					String fieldName = f.getName();
					//set注入,绑定两个对象间的关系,o代表当前对象,调用getObject方法获得对应属性的对象
					f.set(o, getObject(fieldName));
					
				}
			}
		}
	}

}

入口类(主方法)

package writeSpring.spring.beans;

import java.util.List;

import writeSpring.spring.beans.controllor.UserControllor;
import writeSpring.spring.beans.dao.UserDao;
import writeSpring.spring.beans.parse.ComponentScan;
import writeSpring.spring.beans.service.UserService;


public class RunAPP {
	public static void main(String[] args) throws Exception {
		
		//获取bin路径
		String baseDir=RunAPP.class.getResource("/").getPath().substring(1);
		//获取包名
		String pageName=RunAPP.class.getPackage().getName();
		//拼接初始路径
		String Dir=baseDir+pageName.replace(".", "/");
		//传入初始路径包扫描获取路径下所有class文件的路径
		ComponentScan c=new ComponentScan();
		
		List<String> classList=c.Scan(Dir);
		//传入bin路径和集合classList转化为全局限定名(formName参数)
		List<String> className=c.getclassName(baseDir, classList);
		//用反射的方式创建对象放入容器Beans,IoC控制反转
		c.getBean(className);
		//从容器中获取对象使用,由于不允许访问Beans,提供了getObject的方法
		UserService us=c.getObject("userService");
		UserControllor uc=c.getObject("userControllor");
		UserDao ud=c.getObject("userDao");
		//依赖注入DO
		c.DO();
		System.out.println(uc.getone()+"\n"+uc.getAll());
	}
}

	文章的重点是让初学者或不懂spring框架的人了解Spring框架的运行原理,没什么业务逻辑。包扫描Scan()和路径转化getclassName()两个方法其实可以用传统for循环加set注入的方式获取返回值,但我已经写到一半就不打算改了!作为一个初学者,我可能有些地方写的不够准确!但是无所谓,反正你们也打不到我,爱看不看!我已经写的足够详细了!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值