1.IOC介绍
ioc:依赖注入(本人比较喜欢这类描述),字面意思比较好理解,我们在class类中定义的一些对象属性,默认值为null,spring框架自动帮我们注入这些属性的实例对象。不需要再用传统的方式每次使用对象时,在代码中new这个对象,spring默认创建对象的方式是单例(在多线程并发时要注意)。
2.如何实现
问题:定义属性(javaBean对象)时,怎么自动给属性(这个javaBean)赋值
原理:第一步,利用java的反射技术,通过javabean的类路径全名反射生成javabean实例对象;第二步,使用反射通过field中的set方法设置该属性的值为生成的实例对象即可(xml版本中未实现,采用getBean方法)。
3.在xml配置文件中获取类全名
user-annotation.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="userService" class="com.huajie.day1.impl.UserServiceImpl">
</bean>
</beans>
4.使用dom4j,操作xml,获取节点beans中的bean,更加bean的id属性定为到唯一的bean对象,再获取class属性为类路径全名
部分关键代码如下:
// 解析xml文件
public List<Element> readerXML() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document read = saxReader.read(getClassPath(xmlPath));
// 获取根节点
Element rootElement = read.getRootElement();
List<Element> listnodes = rootElement.elements();
return listnodes;
}
private String getBeanClassNameById(List<Element> liste, String beanId){
// 遍历节点获取bean
for (Element element : liste) {
String xmlBeanId = element.attributeValue("id");
if (StringUtils.isEmpty(xmlBeanId)) {
continue;
}
if (beanId.equals(xmlBeanId)) {
String className = element.attributeValue("class");
return className;
}
}
return null;
}
5.使用反射的方式生成javabean实例,返回即可
完整代码如下:
package com.huajie.day1.xml.spring;
import java.io.InputStream;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ClassPathXmlApplicationContext {
private String xmlPath;
public ClassPathXmlApplicationContext(String xmlPath) {
this.xmlPath = xmlPath;
initBeans();
}
private void initBeans() {
// 获取xml中 对象的 ClassPath
// 反射方式创建对象
}
public Object getBean(String beanId) throws Exception {
if (StringUtils.isEmpty(beanId)) {
throw new RuntimeException("beanId不能为空");
}
// 获取xml文件中所有的Bean节点信息
List<Element> liste = readerXML();
if (liste == null || liste.isEmpty()) {
throw new RuntimeException("配置文件中没有bean的信息");
}
String className = getBeanClassNameById(liste, beanId);
if (StringUtils.isEmpty(className)) {
throw new RuntimeException("类路径错误");
}
return newInstance(className);
}
private String getBeanClassNameById(List<Element> liste, String beanId){
// 遍历节点获取bean
for (Element element : liste) {
String xmlBeanId = element.attributeValue("id");
if (StringUtils.isEmpty(xmlBeanId)) {
continue;
}
if (beanId.equals(xmlBeanId)) {
String className = element.attributeValue("class");
return className;
}
}
return null;
}
public Object newInstance(String className) {
try {
return Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 解析xml文件
public List<Element> readerXML() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document read = saxReader.read(getClassPath(xmlPath));
// 获取根节点
Element rootElement = read.getRootElement();
List<Element> listnodes = rootElement.elements();
return listnodes;
}
// 获取当前上下文路径
public InputStream getClassPath(String xmlPath) {
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(xmlPath);
return resourceAsStream;
}
}
6.相关的测试代码文件
package com.huajie.day1.impl;
import org.springframework.stereotype.Service;
import com.huajie.day1.UserService;
@Service("userService")
public class UserServiceImpl implements UserService {
public int add(String a) {
System.out.println("添加");
return 0;
}
}
package com.huajie.day1;
import com.huajie.day1.xml.spring.ClassPathXmlApplicationContext;
public class Test001 {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("user-annotation.xml");
UserService userService = null;
try {
userService = (UserService)app.getBean("userService");
} catch (Exception e) {
e.printStackTrace();
}
userService.add("1");
}
}
package com.huajie.day1;
import org.springframework.stereotype.Service;
public interface UserService {
int add(String a);
}
7.pom.xml文件需要引入dom4j的依赖
<!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
注意:由于是测试版本,xml配置文件和test001.java文件是在同一目录下面
测试效果如下: