版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
利用反射实现Spring的IOC容器
Spring的IOC简介
概念
Spring的核心模块就是IOC机制,IOC是Inversion Of Control简称。
Inversion 反转
对象的获得,原来由程序开发人员自己构造,变成了由Spring指定,由主动获取变成了被动的接收。
Control 控制
控制的是对象的创建,原来由程序开发人员来创建一个对象,现在由Spring容器来创建对象
与MVC三层架构的区别
在MVC架构中,Service调用Dao层时就需要传入一个Dao层的具体的实现类即可。
虽然dao仍然需要创建,但是在结构上却发生了根本的变化,即:对象由原来程序本身创建,变为了程序被动的接收对象。程序员的主要精力放在业务层的实现上。实现了service层和dao层的解耦工作,service层和dao层实现了分离,没有了直接的依赖关系。如果dao层发生了业务的改变,原有的程序不需要发生任何改变,只需要将不同的dao实现类传给Service即可。
Spring框架则实现了完全的解耦,在service对象创建时将会创建一个dao的对象传入到service中,Spring将这种实现通过以下配置来完成。
步骤
1.首先创建一个简单的pojo
package com.langsin.pojo;
public class Book {
private String bookId;
private String bookName;
public Double price;
public Book(String bookId,String bookName,Double price) {
this.bookId=bookId;
this.bookName = bookName;
this.price = price;
}
public Book(){
}
public String getBookId() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public Book(String bookId, String bookName, Double price) {
this.bookId = bookId;
this.bookName = bookName;
this.price = price;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Book [bookId=" + bookId + ", bookName=" + bookName + ", price=" + price + "]";
}
}
2.在xml中配置Book的bean
<---! 引入了c命名空间->
<bean id="book" name="bo1,bo2"
class="com.langsin.pojo.Book" c:bookId="B001"
c:bookName="数学" c:price="12.25">
3.在pom.xml中加入jdom
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
4.创建一个beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="book" class="com.langsin.pojo.Book">
<attr property="bookName" value="Java基础"/>
</bean>
<bean id="user" class="com.langsin.pojo.User">
<attr property="userName" value="张三"/>
</bean>
</beans>
5.利用反射手写IOC并测试
public void testReflect() throws Exception{
//创建一个容器
Map<String,Object> container = new HashMap<>();
//自己实现的Spring的IOC容器
SAXBuilder builder = new SAXBuilder();
InputStream stream = new FileInputStream("./src/main/resources/beans.xml");
Document dom = builder.build(stream);
//获取根节点
Element root = dom.getRootElement();
//返回的是子节点的集合
List<Element> children = root.getChildren();
for (Element child : children) {
//获取类
String classPath = child.getAttributeValue("class");
//通过反射获取类
Class<?> clazz = Class.forName(classPath);
//获取对象的唯一标识
String id= child.getAttributeValue("id");
Object obj = clazz.newInstance();
container.put(id, obj);
List<Element> attrList = child.getChildren();
for (Element attr : attrList) {
String filed = attr.getAttributeValue("property");
String value = attr.getAttributeValue("value");
//通过反射获取对应的方法
String name = this.getMethodName(filed);
Method method = clazz.getMethod(name, new Class[] {String.class});
method.invoke(obj, new Object[] {value});
}
}
System.out.println("ioc容器启动");
Book book = (Book) container.get("book");
System.out.println(book.getBookName());
User user = (User) container.get("user");
System.out.println(user.getUserName());
}