├── demo ├── src │ └── main │ │ ├── java │ │ └── shop │ │ │ └── stopyc │ │ │ ├── dao │ │ │ ├── UserDao.java │ │ │ └── impl │ │ │ │ └── UserDaoImpl.java │ │ │ ├── service │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ │ └── UserServiceImpl.java │ │ │ └── controller │ │ │ └── UserController.java │ │ └── resources │ │ └── applicationContext.xml └── pom.xml ├── .gitignore └── spring-demo ├── src └── main │ └── java │ └── shop │ └── stopyc │ └── framework │ ├── context │ ├── ApplicationContext.java │ └── support │ │ ├── AbstractApplicationContext.java │ │ └── ClassPathXmlApplicationContext.java │ ├── utils │ └── StringUtils.java │ └── beans │ ├── factory │ ├── support │ │ ├── BeanDefinitionReader.java │ │ ├── BeanDefinitionRegistry.java │ │ └── SimpleBeanDefinitionRegistry.java │ ├── BeanFactory.java │ └── xml │ │ └── XmlBeanDefinitionReader.java │ ├── PropertyValue.java │ ├── BeanDefinition.java │ └── MutablePropertyValues.java └── pom.xml /demo/src/main/java/shop/stopyc/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.dao; 2 | 3 | /** 4 | * @version v1.0 5 | * @ClassName: UserDao 6 | * @Description: 数据访问层接口 7 | * @Author: YC104 8 | */ 9 | public interface UserDao { 10 | 11 | public void add(); 12 | } 13 | -------------------------------------------------------------------------------- /demo/src/main/java/shop/stopyc/service/UserService.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.service; 2 | 3 | /** 4 | * @version v1.0 5 | * @ClassName: UserService 6 | * @Description: 业务逻辑层接口 7 | * @Author: YC104 8 | */ 9 | public interface UserService { 10 | 11 | public void add(); 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | replay_pid* 25 | -------------------------------------------------------------------------------- /demo/src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/context/ApplicationContext.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.context; 2 | 3 | 4 | import shop.stopyc.framework.beans.factory.BeanFactory; 5 | 6 | /** 7 | * @version v1.0 8 | * @ClassName: ApplicationContext 9 | * @Description: 定义非延时加载功能 10 | * @Author: YC104 11 | */ 12 | public interface ApplicationContext extends BeanFactory { 13 | 14 | /** 15 | * 加载配置文件,把bean加入注册表 16 | * @throws Exception: 17 | */ 18 | void refresh() throws Exception; 19 | } 20 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.utils; 2 | 3 | /** 4 | * @version v1.0 5 | * @ClassName: StringUtils 6 | * @Description: 字符串工具类 7 | * @Author: YC104 8 | */ 9 | public class StringUtils { 10 | private StringUtils() { 11 | 12 | } 13 | 14 | /** 15 | * userDao ==> setUserDao 16 | * @param fieldName :依赖名称 17 | * @return :set方法名称 18 | */ 19 | public static String getSetterMethodByFieldName(String fieldName) { 20 | return "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/factory/support/BeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans.factory.support; 2 | 3 | /** 4 | * @version v1.0 5 | * @ClassName: BeanDefinitionReader 6 | * @Description: 7 | * 用来解析配置文件的,而该接口只是定义了规范 8 | * @Author: YC104 9 | */ 10 | public interface BeanDefinitionReader { 11 | /** 12 | * 获取注册表对象 13 | * @return: 注册表对象 14 | */ 15 | BeanDefinitionRegistry getRegistry(); 16 | 17 | /** 18 | * 加载配置文件并在注册表中进行注册 19 | * @param configLocation: 配置文件名称 20 | * @throws Exception: io 21 | */ 22 | void loadBeanDefinitions(String configLocation) throws Exception; 23 | } 24 | -------------------------------------------------------------------------------- /spring-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | shop.stopyc 8 | spring-demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 14 | dom4j 15 | dom4j 16 | 1.1 17 | 18 | 19 | -------------------------------------------------------------------------------- /demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | demo 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | shop.stopyc 14 | spring-demo 15 | 1.0-SNAPSHOT 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /demo/src/main/java/shop/stopyc/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.service.impl; 2 | 3 | 4 | import shop.stopyc.dao.UserDao; 5 | import shop.stopyc.service.UserService; 6 | 7 | /** 8 | * @version v1.0 9 | * @ClassName: UserServiceImpl 10 | * @Description: 业务逻辑层实现类 11 | * @Author: YC104 12 | */ 13 | public class UserServiceImpl implements UserService { 14 | 15 | //声明一个UserDao类型的变量 16 | private UserDao userDao; 17 | 18 | public UserServiceImpl() { 19 | System.out.println("userService被创建了"); 20 | } 21 | 22 | public void setUserDao(UserDao userDao) { 23 | this.userDao = userDao; 24 | } 25 | 26 | public void add() { 27 | System.out.println("UserService ..."); 28 | userDao.add(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/factory/BeanFactory.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans.factory; 2 | 3 | /** 4 | * @version v1.0 5 | * @ClassName: BeanFactory 6 | * @Description: IOC容器父接口 7 | * @Author: YC104 8 | */ 9 | public interface BeanFactory { 10 | 11 | /** 12 | * 工厂中获取bean对象 13 | * @param name :beanName 14 | * @return :beanObj 15 | * @throws Exception : cast exception 16 | */ 17 | Object getBean(String name) throws Exception; 18 | 19 | /** 20 | * 工厂中获取bean对象 21 | * @param name :beanName; 22 | * @param clazz : 字节码 23 | * @param :类型 24 | * @return: bean 25 | * @throws Exception :cast exception 26 | */ 27 | T getBean(String name, Class clazz) throws Exception; 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/main/java/shop/stopyc/dao/impl/UserDaoImpl.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.dao.impl; 2 | 3 | 4 | import shop.stopyc.dao.UserDao; 5 | 6 | /** 7 | * @version v1.0 8 | * @ClassName: UserDaoImpl 9 | * @Description: 数据访问层实现类 10 | * @Author: YC104 11 | */ 12 | public class UserDaoImpl implements UserDao { 13 | 14 | private String username; 15 | private String password; 16 | 17 | public void setUsername(String username) { 18 | this.username = username; 19 | } 20 | 21 | public void setPassword(String password) { 22 | this.password = password; 23 | } 24 | 25 | public UserDaoImpl() { 26 | System.out.println("userDao被创建了"); 27 | } 28 | 29 | public void add() { 30 | System.out.println("UserDao ..." + username + "==" + password); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /demo/src/main/java/shop/stopyc/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.controller; 2 | 3 | 4 | import shop.stopyc.framework.context.ApplicationContext; 5 | import shop.stopyc.framework.context.support.ClassPathXmlApplicationContext; 6 | import shop.stopyc.service.UserService; 7 | 8 | /** 9 | * @version v1.0 10 | * @ClassName: UserController 11 | * @Description: TODO(一句话描述该类的功能) 12 | * @Author: YC104 13 | */ 14 | public class UserController { 15 | public static void main(String[] args) throws Exception { 16 | //1,创建spring的容器对象 17 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); 18 | //BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); 19 | //2,从容器对象中获取userService对象 20 | UserService userService = applicationContext.getBean("userService", UserService.class); 21 | //3,调用userService方法进行业务逻辑处理 22 | userService.add(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/PropertyValue.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans; 2 | 3 | /** 4 | * bean被依赖的属性类 5 | * 6 | * @author YC104 7 | */ 8 | public class PropertyValue { 9 | 10 | private String name; 11 | private String ref; 12 | private String value; 13 | 14 | public PropertyValue() { 15 | } 16 | 17 | public PropertyValue(String name, String ref, String value) { 18 | this.name = name; 19 | this.ref = ref; 20 | this.value = value; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public String getRef() { 32 | return ref; 33 | } 34 | 35 | public void setRef(String ref) { 36 | this.ref = ref; 37 | } 38 | 39 | public String getValue() { 40 | return value; 41 | } 42 | 43 | public void setValue(String value) { 44 | this.value = value; 45 | } 46 | } -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/BeanDefinition.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans; 2 | 3 | 4 | /** 5 | * @version v1.0 6 | * @ClassName: BeanDefinition 7 | * @Description: 用来封装bean标签数据 8 | *

9 | * class属性 10 | * property子标签的数据(一些依赖的属性) 11 | * @Author: YC104 12 | */ 13 | public class BeanDefinition { 14 | 15 | /** 16 | * bean唯一id 17 | */ 18 | private String id; 19 | /** 20 | * 全类名 21 | */ 22 | private String className; 23 | 24 | /** 25 | * property属性(bean中会有很多的依赖,这里采用集合,使用了迭代器模式) 26 | */ 27 | private MutablePropertyValues propertyValues; 28 | 29 | public BeanDefinition() { 30 | propertyValues = new MutablePropertyValues(); 31 | } 32 | 33 | public String getId() { 34 | return id; 35 | } 36 | 37 | public void setId(String id) { 38 | this.id = id; 39 | } 40 | 41 | public String getClassName() { 42 | return className; 43 | } 44 | 45 | public void setClassName(String className) { 46 | this.className = className; 47 | } 48 | 49 | public MutablePropertyValues getPropertyValues() { 50 | return propertyValues; 51 | } 52 | 53 | public void setPropertyValues(MutablePropertyValues propertyValues) { 54 | this.propertyValues = propertyValues; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/factory/support/BeanDefinitionRegistry.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans.factory.support; 2 | 3 | 4 | import shop.stopyc.framework.beans.BeanDefinition; 5 | 6 | /** 7 | * @version v1.0 8 | * @ClassName: BeanDefinitionRegistry 9 | * @Description: 注册表对象 10 | * @Author: YC104 11 | */ 12 | public interface BeanDefinitionRegistry { 13 | /** 14 | * 注册BeanDefinition对象到注册表中 15 | * @param beanName :bean name 16 | * @param beanDefinition :bean definition 17 | */ 18 | void registerBeanDefinition(String beanName, BeanDefinition beanDefinition); 19 | 20 | /** 21 | * 从注册表中删除指定名称的BeanDefinition对象 22 | * @param beanName :bean name 23 | * @throws Exception: null 24 | */ 25 | void removeBeanDefinition(String beanName) throws Exception; 26 | 27 | /** 28 | * 根据名称从注册表中获取BeanDefinition对象 29 | * @param beanName: bean name 30 | * @return: BeanDefinition对象 31 | * @throws Exception: 获取不到 32 | */ 33 | BeanDefinition getBeanDefinition(String beanName) throws Exception; 34 | 35 | /** 36 | * 判断注册表中是否含有该bean 37 | * @param beanName :bean name; 38 | * @return: bool 39 | */ 40 | boolean containsBeanDefinition(String beanName); 41 | 42 | /** 43 | * 获取注册表中bean的数量 44 | * @return :数量 45 | */ 46 | int getBeanDefinitionCount(); 47 | 48 | /** 49 | * 获取注册表中所有bean的名称 50 | * @return :bean名称字符串数组 51 | */ 52 | String[] getBeanDefinitionNames(); 53 | } 54 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/factory/support/SimpleBeanDefinitionRegistry.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans.factory.support; 2 | 3 | 4 | import shop.stopyc.framework.beans.BeanDefinition; 5 | 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | /** 10 | * @version v1.0 11 | * @ClassName: SimpleBeanDefinitionRegistry 12 | * @Description: 注册表接口的子实现类 13 | * @Author: YC104 14 | */ 15 | public class SimpleBeanDefinitionRegistry implements BeanDefinitionRegistry { 16 | 17 | /** 18 | * 定义一个容器,用来存储BeanDefinition对象 19 | */ 20 | private final Map beanDefinitionMap = new ConcurrentHashMap(); 21 | 22 | public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) { 23 | beanDefinitionMap.put(beanName,beanDefinition); 24 | } 25 | 26 | public void removeBeanDefinition(String beanName) throws Exception { 27 | beanDefinitionMap.remove(beanName); 28 | } 29 | 30 | public BeanDefinition getBeanDefinition(String beanName) throws Exception { 31 | return beanDefinitionMap.get(beanName); 32 | } 33 | 34 | public boolean containsBeanDefinition(String beanName) { 35 | return beanDefinitionMap.containsKey(beanName); 36 | } 37 | 38 | public int getBeanDefinitionCount() { 39 | return beanDefinitionMap.size(); 40 | } 41 | 42 | public String[] getBeanDefinitionNames() { 43 | return beanDefinitionMap.keySet().toArray(new String[0]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/context/support/AbstractApplicationContext.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.context.support; 2 | 3 | 4 | import shop.stopyc.framework.beans.factory.support.BeanDefinitionReader; 5 | import shop.stopyc.framework.beans.factory.support.BeanDefinitionRegistry; 6 | import shop.stopyc.framework.context.ApplicationContext; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | /** 13 | * @version v1.0 14 | * @ClassName: AbstractApplicationContext 15 | * @Description: ApplicationContext接口的子实现类,用于立即加载 16 | * @Author: 黑马程序员 17 | */ 18 | public abstract class AbstractApplicationContext implements ApplicationContext { 19 | 20 | /** 21 | * 声明解析器变量 22 | */ 23 | protected BeanDefinitionReader beanDefinitionReader; 24 | 25 | /** 26 | * 定义用于存储bean对象的map容器 27 | */ 28 | protected Map singletonObjects = new ConcurrentHashMap(); 29 | 30 | /** 31 | * 声明配置文件路径的变量 32 | */ 33 | protected String configLocation; 34 | 35 | public void refresh() throws Exception { 36 | //加载BeanDefinition对象进注册表中 37 | beanDefinitionReader.loadBeanDefinitions(configLocation); 38 | //初始化bean 39 | finishBeanInitialization(); 40 | } 41 | 42 | /** 43 | * bean的初始化 44 | * @throws Exception: 45 | */ 46 | private void finishBeanInitialization() throws Exception { 47 | //获取注册表对象 48 | BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry(); 49 | 50 | //获取BeanDefinition对象 51 | String[] beanNames = registry.getBeanDefinitionNames(); 52 | for (String beanName : beanNames) { 53 | //进行bean的初始化 54 | getBean(beanName); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/MutablePropertyValues.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | import java.util.concurrent.CopyOnWriteArrayList; 6 | 7 | /** 8 | * @version v1.0 9 | * @ClassName: MutablePropertyValues 10 | * @Description: 用户存储和管理多个PropertyValue对象(迭代器模式) 11 | * @Author: YC104 12 | */ 13 | public class MutablePropertyValues implements Iterable { 14 | 15 | /** 16 | * 定义list集合对象,用来存储PropertyValue对象 17 | */ 18 | private final List propertyValueList; 19 | 20 | public MutablePropertyValues() { 21 | this.propertyValueList = new CopyOnWriteArrayList(); 22 | } 23 | 24 | public MutablePropertyValues(List propertyValueList) { 25 | if (propertyValueList == null) { 26 | this.propertyValueList = new CopyOnWriteArrayList(); 27 | } else { 28 | this.propertyValueList = propertyValueList; 29 | } 30 | } 31 | 32 | /** 33 | * 获取所有的PropertyValue对象,返回以数组的形式 34 | * @return 集合变为数组 35 | */ 36 | public PropertyValue[] getPropertyValues() { 37 | //将集合转换为数组并返回 38 | return propertyValueList.toArray(new PropertyValue[0]); 39 | } 40 | 41 | /** 42 | * 根据name属性值获取PropertyValue对象 43 | * @param propertyName :属性名称 44 | * @return :属性对象 45 | */ 46 | public PropertyValue getPropertyValue(String propertyName) { 47 | //遍历集合对象 48 | for (PropertyValue propertyValue : propertyValueList) { 49 | if (propertyValue.getName().equals(propertyName)) { 50 | return propertyValue; 51 | } 52 | } 53 | return null; 54 | } 55 | 56 | /** 57 | * 判断集合是否为空 58 | * @return :true or false 59 | */ 60 | public boolean isEmpty() { 61 | return propertyValueList.isEmpty(); 62 | } 63 | 64 | /** 65 | * 添加PropertyValue对象 66 | * @param pv :属性对象 67 | * @return: 属性对象列表, 为了链式编程 68 | */ 69 | public MutablePropertyValues addPropertyValue(PropertyValue pv) { 70 | //判断集合中存储的PropertyValue对象是否和传递进行的重复了,如果重复了,进行覆盖 71 | for (int i = 0; i < propertyValueList.size(); i++) { 72 | //获取集合中每一个PropertyValue对象 73 | PropertyValue currentPv = propertyValueList.get(i); 74 | if (currentPv.getName().equals(pv.getName())) { 75 | propertyValueList.set(i, pv); 76 | return this; 77 | } 78 | } 79 | this.propertyValueList.add(pv); 80 | return this; 81 | } 82 | 83 | /** 84 | * 判断是否有指定name属性值的对象 85 | * @param propertyName :属性名 86 | * @return :bool 87 | */ 88 | public boolean contains(String propertyName) { 89 | return getPropertyValue(propertyName) != null; 90 | } 91 | 92 | /** 93 | * 获取迭代器对象 94 | * @return :迭代器对象 95 | */ 96 | public Iterator iterator() { 97 | return propertyValueList.iterator(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/beans/factory/xml/XmlBeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.beans.factory.xml; 2 | 3 | import org.dom4j.Document; 4 | import org.dom4j.Element; 5 | import org.dom4j.io.SAXReader; 6 | import shop.stopyc.framework.beans.BeanDefinition; 7 | import shop.stopyc.framework.beans.MutablePropertyValues; 8 | import shop.stopyc.framework.beans.PropertyValue; 9 | import shop.stopyc.framework.beans.factory.support.BeanDefinitionReader; 10 | import shop.stopyc.framework.beans.factory.support.BeanDefinitionRegistry; 11 | import shop.stopyc.framework.beans.factory.support.SimpleBeanDefinitionRegistry; 12 | 13 | import java.io.InputStream; 14 | import java.util.List; 15 | 16 | /** 17 | * @version v1.0 18 | * @ClassName: XmlBeanDefinitionReader 19 | * @Description: 针对xml配置文件进行解析的类 20 | * @Author: YC104 21 | */ 22 | public class XmlBeanDefinitionReader implements BeanDefinitionReader { 23 | 24 | /** 25 | * 声明注册表对象 26 | */ 27 | private final BeanDefinitionRegistry registry; 28 | 29 | public XmlBeanDefinitionReader() { 30 | registry = new SimpleBeanDefinitionRegistry(); 31 | } 32 | 33 | public BeanDefinitionRegistry getRegistry() { 34 | return registry; 35 | } 36 | 37 | public void loadBeanDefinitions(String configLocation) throws Exception { 38 | //使用dom4j进行xml配置文件的解析 39 | SAXReader reader = new SAXReader(); 40 | //获取类路径下的配置文件 41 | InputStream is = XmlBeanDefinitionReader.class.getClassLoader().getResourceAsStream(configLocation); 42 | Document document = reader.read(is); 43 | //根据Document对象获取根标签对象 (beans) 44 | Element rootElement = document.getRootElement(); 45 | //获取根标签下所有的bean标签对象 46 | List beanElements = rootElement.elements("bean"); 47 | //遍历集合 48 | for (Element beanElement : beanElements) { 49 | //获取id属性 50 | String id = beanElement.attributeValue("id"); 51 | //获取class属性 52 | String className = beanElement.attributeValue("class"); 53 | 54 | //将id属性和class属性封装到BeanDefinition对象中 55 | //1,创建BeanDefinition 56 | BeanDefinition beanDefinition = new BeanDefinition(); 57 | beanDefinition.setId(id); 58 | beanDefinition.setClassName(className); 59 | 60 | //创建MutablePropertyValues对象 61 | MutablePropertyValues mutablePropertyValues = new MutablePropertyValues(); 62 | 63 | //获取bean标签下所有的property标签对象 64 | List propertyElements = beanElement.elements("property"); 65 | for (Element propertyElement : propertyElements) { 66 | String name = propertyElement.attributeValue("name"); 67 | String ref = propertyElement.attributeValue("ref"); 68 | String value = propertyElement.attributeValue("value"); 69 | PropertyValue propertyValue = new PropertyValue(name, ref, value); 70 | mutablePropertyValues.addPropertyValue(propertyValue); 71 | } 72 | //将mutablePropertyValues对象封装到BeanDefinition对象中 73 | beanDefinition.setPropertyValues(mutablePropertyValues); 74 | 75 | //将beanDefinition对象注册到注册表中 76 | registry.registerBeanDefinition(id, beanDefinition); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /spring-demo/src/main/java/shop/stopyc/framework/context/support/ClassPathXmlApplicationContext.java: -------------------------------------------------------------------------------- 1 | package shop.stopyc.framework.context.support; 2 | 3 | 4 | import shop.stopyc.framework.beans.BeanDefinition; 5 | import shop.stopyc.framework.beans.MutablePropertyValues; 6 | import shop.stopyc.framework.beans.PropertyValue; 7 | import shop.stopyc.framework.beans.factory.support.BeanDefinitionRegistry; 8 | import shop.stopyc.framework.beans.factory.xml.XmlBeanDefinitionReader; 9 | import shop.stopyc.framework.utils.StringUtils; 10 | 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * @version v1.0 15 | * @ClassName: ClassPathXmlApplicationContext 16 | * @Description: IOC容器具体的子实现类 17 | * 用于加载类路径下的xml格式的配置文件 18 | * @Author: YC104 19 | */ 20 | public class ClassPathXmlApplicationContext extends AbstractApplicationContext { 21 | 22 | public ClassPathXmlApplicationContext(String configLocation) { 23 | this.configLocation = configLocation; 24 | //构建解析器对象 25 | beanDefinitionReader = new XmlBeanDefinitionReader(); 26 | try{ 27 | this.refresh(); 28 | } catch (Exception ignored){} {} 29 | } 30 | 31 | /** 32 | * 根据bean对象的名称获取bean对象 33 | * @param name :beanName :bean name 34 | * @return :bean对象 35 | * @throws Exception: 36 | */ 37 | public Object getBean(String name) throws Exception { 38 | //判断对象容器中是否包含指定名称的bean对象,如果包含,直接返回即可,如果不包含,需要自行创建 39 | Object obj = singletonObjects.get(name); 40 | if (obj != null) { 41 | return obj; 42 | } 43 | 44 | //获取BeanDefinition对象 45 | BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry(); 46 | BeanDefinition beanDefinition = registry.getBeanDefinition(name); 47 | //获取bean信息中的className 48 | String className = beanDefinition.getClassName(); 49 | //通过反射创建对象 50 | Class clazz = Class.forName(className); 51 | Object beanObj = clazz.newInstance(); 52 | 53 | //进行依赖注入操作 54 | MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); 55 | for (PropertyValue propertyValue : propertyValues) { 56 | //获取name属性值 57 | String propertyName = propertyValue.getName(); 58 | //获取value属性 59 | String value = propertyValue.getValue(); 60 | //获取ref属性 61 | String ref = propertyValue.getRef(); 62 | if(ref != null && !"".equals(ref)) { 63 | //获取依赖的bean对象 64 | Object bean = getBean(ref); 65 | //拼接方法名 66 | String methodName = StringUtils.getSetterMethodByFieldName(propertyName); 67 | //获取所有的方法对象 68 | Method[] methods = clazz.getMethods(); 69 | for (Method method : methods) { 70 | if (methodName.equals(method.getName())) { 71 | //执行该setter方法 72 | method.invoke(beanObj,bean); 73 | } 74 | } 75 | } 76 | 77 | if(value != null && !"".equals(value)) { 78 | //拼接方法名 79 | String methodName = StringUtils.getSetterMethodByFieldName(propertyName); 80 | //获取method对象 81 | Method method = clazz.getMethod(methodName, String.class); 82 | method.invoke(beanObj,value); 83 | } 84 | } 85 | 86 | //在返回beanObj对象之前,将该对象存储到map容器中 87 | singletonObjects.put(name,beanObj); 88 | return beanObj; 89 | } 90 | 91 | public T getBean(String name, Class clazz) throws Exception { 92 | Object bean = getBean(name); 93 | if(bean == null) { 94 | return null; 95 | } 96 | return clazz.cast(bean); 97 | } 98 | } 99 | --------------------------------------------------------------------------------