极简spring框架实现
备注:无任何实际用途 仅做学习spring框架思想用
package stu.adam.spring.factory; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; /** * @program: simpleSpring * @description: 工厂 * @author: adam * @create: 2021-12-15 17:17 **/ public class SimpleBeanFactory { private static final HashMapfactory = new HashMap<>(); public static Object createBean(String className) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { return createBean(className,true); } // 建bean public static Object createBean(String className,boolean single) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // 实例 Object instance=null; //反射取得字节码对象(钥匙) //i.使用反射获取自字节码对象 Class<?> aClass=Class.forName(className); //拿接口 if(single){ Object instanceByInterface = getInstanceByInterface(aClass); if(instanceByInterface!=null){ return instanceByInterface; } } // ii.根据字节码对象获取获取无参构造 //无参构造 Constructor<?> constructor=aClass.getConstructor(); //iii..根据无参构造创建对象 //设置对象属性值 instance=constructor.newInstance();//实例 //设置属性的值 setField(aClass,instance); Class<?>[] aClassInterfaces = aClass.getInterfaces(); for (Class<?> aClassInterface : aClassInterfaces) { factory.put(aClassInterface,instance); } return instance; } private static Object getInstanceByInterface(Class aclass){ Object o=null; // 获取接口列表 Class<?>[] interfaces=aclass.getInterfaces(); for (Class<?> anInterface : interfaces) { o=factory.get(anInterface); if(o != null){ return o; } } return o; } private static void setField(Class clazz,Object instance){ Field[] declaredFileds=clazz.getDeclaredFields(); //遍历属性 for (Field filed : declaredFileds) { //遍历成员属性 Class<?>type=filed.getType(); Object o=factory.get(type); if(o!=null){ filed.setAccessible(true); try { //设置属性 filed.set(instance,o); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } }
放“bean”的地方
主要创建"bean"的方法类:
思路:
1.设置实例 instance 为空
2.反射(传入的class)获得字节码对象(字节码就像一个钥匙,有这把就可以拿到很多东西)
3.默认为单例 补充:单例放到map缓存里,多例直接放到heap(堆)里
4.通过字节码拿到接口(a)
5.通过字节码拿到所有无参构造(b)
6.通过无参构造创建对象(c)
7.设置对象的属性值
取得实例(对象)
设置属性值
8.将所有实例放到工厂里面
9.返回实例
dao ,impl ,test
package stu.adam.spring.dao; public interface UserDao { void test(); }
package stu.adam.spring.dao.impl; import stu.adam.spring.dao.UserDao; /** * @program: simpleSpring * @description: * @author: adam * @create: 2021-12-15 17:56 **/ public class UserDaoImpl implements UserDao { @Override public void test() { System.out.println("我是test"); } public UserDaoImpl() { System.out.println("我是daoimpl的无参构造方法"); } }
package stu.adam.spring; import stu.adam.spring.factory.SimpleBeanFactory; import sun.applet.Main; import java.lang.reflect.InvocationTargetException; /** * @program: simpleSpring * @description: * @author: adam * @create: 2021-12-15 17:13 **/ public class as { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { String path="stu.adam.spring.dao.impl.UserDaoImpl"; SimpleBeanFactory.createBean(path); SimpleBeanFactory.createBean(path); SimpleBeanFactory.createBean(path); path="stu.adam.spring.service.Impl.UserServiceImpl.UserServiceImpl"; Object bean=SimpleBeanFactory.createBean(path,false); System.out.println(bean); } }-