常规Spring IOC实现
Spring 依赖 :
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
spring-context 会自动将 spring-core、spring-beans、spring-aop、spring-expression 这几个基础 jar 包带进来。
User:
public class User {
private String userId;
private String userName;
public User() {
}
public User(String userId, String userName) {
this.userId = userId;
this.userName = userName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", userName='" + userName + '\'' +
'}';
}
}
user.xml
xml格式一定要是spring提供的标准模式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user1" class="springdemo.cy.bean.User">
<property name="userId" value="0001"></property>
<property name="userName" value="张三"></property>
</bean>
<bean id="user2" class="springdemo.cy.bean.User">
<constructor-arg name="userId" value="0002"></constructor-arg>
<constructor-arg name="userName" value="李四"></constructor-arg>
</bean>
</beans>
测试demo:
public class test {
public static void main(String[] args) {
ApplicationContext appLication = new ClassPathXmlApplicationContext("user.xml");
Object bean = appLication.getBean("user1");
User user = (User) bean;
System.out.println(user);
}
}
用dom4j解析xml 模拟spring
dom4j 依赖:
dom4j相关知识: https://blog.csdn.net/weixin_48052161/article/details/115053853
<!--用于解析xml -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
自定义xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="user1" class="springdemo.cy.bean.User">
<property name="userId" value="0001"></property>
<property name="userName" value="张三"></property>
</bean>
<bean id="user2" class="springdemo.cy.bean.User">
<property name="userId" value="0002"></property>
<property name="userName" value="李四"></property>
</bean>
</beans>
模拟一个 ClassPathXmlApplicationContext对象
这里是通过set方法注入 还可以通过构造方法 反射注入
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ClassPathXmlApplicationContext {
/**
* 模拟spring管理对象的容器
*/
Map<String,Object> map =new HashMap<>();
public ClassPathXmlApplicationContext(String xmlPath) throws Exception {
//模拟spring项目启动扫描
init(xmlPath);
}
/**
* 获取Bean对象
* @param xmlPath
* @throws Exception
*/
public void init(String xmlPath) throws Exception{
// 1.读取xml配置文件
// 1.1创建xml解析器
SAXReader saxReader = new SAXReader();
// 1.2读取xml配置文件
Document read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
// 1.3获取xml配置文件的根节点对象(<beans></beans>)
Element rootElement = read.getRootElement();
//1.4获取根节点中所有的子节点对象,也就是所有bean对象(<bean></bean>)
List<Element> beanElements = rootElement.elements();
Object obj = null;
for (Element beanElement : beanElements) {
// 2.使用beanId查找bean配置,并获取配置文件中class的地址(为了与参数beanId区分开,我们命名为beanElementId)
//2.1使用beanId查找bean配置
String beanElementId = beanElement.attributeValue("id");
// 2.2获取bean对应的Class地址
String beanClassPath = beanElement.attributeValue("class");
// 3.使用反射实例化对象
// 3.1获取Class对象
Class<?> cls = Class.forName(beanClassPath);
// 3.2实例化对象
obj = cls.newInstance();
// 4.获取属性配置,使用反射技术进行赋值
// 4.1获取所有属性
List<Element> fieldElements = beanElement.elements();
for (Element fieldElement : fieldElements) {
String name = fieldElement.attributeValue("name");
String value = fieldElement.attributeValue("value");
// 4.2使用反射api为私有属性赋值
Field declaredField = cls.getDeclaredField(name);
//忽略访问权限修饰符的安全检查,又称为暴力反射
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
//生成的bean对象放入map容器
map.put(beanElementId,obj);
}
}
//从map提取相应的bean对象
public Object getBean(String name){
return map.get(name);
}
}
测试demo:
public class SpringIOCDemo {
public static void main(String[] args) throws Exception {
//读取User的XML配置文件
ClassPathXmlApplicationContext appLication = new ClassPathXmlApplicationContext("user01.xml");
//获取User的Bean对象
Object bean = appLication.getBean("user1");
User user = (User) bean;
System.out.println(user);
}
}