续上篇,在解决完配置文件的解析之后,写了一个简单addUser模块准备测试
model代码:
package com.l.model; public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
DAO(接口代码未贴出)
package com.l.impl; import com.l.dao.UserDAO; import com.l.model.User; public class UserDAOImpl implements UserDAO { @Override public void save(User u) { System.out.println("Success!"); } }
UserService代码:
package com.l.service;
import com.l.dao.UserDAO;
import com.l.model.User;
public class UserService {
private UserDAO dao;//标红
public UserDAO getUserDAO() {
return dao;
}
public void setUserDAO(UserDAO dao) {
this.dao = dao;
}
public void add(User user) {
dao.save(user);
}
}
下面进行测试:
package com.l.service; import java.io.IOException; import org.junit.Test; import com.l.impl.UserDAOImpl; import com.l.model.User; public class UserServiceTset { @Test public void addTest() throws IOException, Exception{ UserService service = new UserService(); User u = new User(); service.add(u); } }
当你测试完,会报一个空指针错误,这是因为UserService中没有new一个UserDAO对象,这就是spring的好处,不用自己进行手动创建对象。是怎么实现的呢?
在spring中有这样一个配置文件,叫beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="u" class="com.l.impl.UserDAO"> </bean> </beans>
使用上篇的方法对其进行解析
package com.l.spring; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; public class ClassPathXMLApplicationContext implements BeanFactory{ private Map<String, Object> beans = new HashMap<String, Object>(); public ClassPathXMLApplicationContext() throws Exception, IOException{ SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(this.getClass() .getClassLoader().getResourceAsStream("beans.xml")); Element root = doc.getRootElement(); List<Element> elements = root.getChildren("bean"); for (int i = 0; i < elements.size(); i++) { Element element = elements.get(i); String id = element.getAttributeValue("id"); String clazz = element.getAttributeValue("class");//获取UserDAO的类名 System.out.println(id + " : " + clazz); Object o = Class.forName(clazz).newInstance();//为UserDAO创建一个对象 beans.put(id, o); } } @Override //通过getBean获取为UserDAO创建的对象 public Object getBean(String id) { return beans.get(id); } }
通过解析beans.xml中的类名,为其创建对象,实现BeanFactory中的getBea()方法,让外界获取该对象
BeanFactory接口:
package com.l.spring; public interface BeanFactory { public Object getBean(String name); }
再次对其进行测试:
package com.l.service; import java.io.IOException; import org.junit.Test; import com.l.impl.UserDAOImpl; import com.l.model.User; import com.l.spring.BeanFactory; import com.l.spring.ClassPathXMLApplicationContext; public class UserServiceTset { @Test public void addTest() throws IOException, Exception{ BeanFactory factory = new ClassPathXMLApplicationContext(); UserService service = new UserService(); UserDAO userDAO = (UserDAO) factory.getBean("u"); service.setUserDao(userDAO); User u = new User(); u.setName("nimA"); u.setPassword("heh"); service.add(u); } }
通过测试
通过BeanFactory来实例化,管理对象,使用它的实现类ClassPathXmlApplicationContext来新建对象,将配置文件中对应的id和对象放入Map中。
再想一下,既然UserDAO可以这样来实现,那么UserService也是可以的:
在beans.xml中加入再添加一个bean标签<bean id="userService" class="com.l.service.UserService">
测试代码:
package com.l.service; import java.io.IOException; import org.junit.Test; import com.l.impl.UserDAOImpl; import com.l.model.User; import com.l.spring.BeanFactory; import com.l.spring.ClassPathXMLApplicationContext; public class UserServiceTset { @Test public void addTest() throws IOException, Exception{ BeanFactory factory = new ClassPathXMLApplicationContext(); UserDAO userDAO = (UserDAO) factory.getBean("u"); UserService service = (UserService)factory.getBean("userService");//标红 service.setUserDao(userDAO); User u = new User(); service.add(u); } }代码中标红部分, 分两次调用了getBean方法,然而却是没有这个必要的。在bean.xml中<bean>下添加一个子标签<property>
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="u" class="com.l.impl.UserDAOImpl"/> <bean id="userService" class="com.l.service.UserService"> <property name="userDAO" bean="u"/> </bean> </beans>property是告诉你,“userService”中有一个setUserDAO的方法,当调用该方法时,将后面指定的bean传进去,这种方法叫做注入:
注入代码:
List<Element> property = element.getChildren("property"); for(Element propertyElement : property) { String name = propertyElement.getAttributeValue("name"); //userDAO String bean = propertyElement.getAttributeValue("bean"); //u Object beanObject = beans.get(bean);//UserDAOImpl instance String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]); // System.out.println(m.getName()); m.invoke(o, beanObject); }将这段代码加到解析bean.xml的java文件的for循环中,此处用到的是反射机制,通过解析配置文件,Map中存有<"u", 相应对象><"userService", 相应对象>,配置文件中第一个<bean>标签下没有<property>,循环至第二个,即"userService" 取出”userService“中的setUserDAO方法,最后通过invoke(obj,args)实现注入,参数obj为调用该方法的对象(此处为o),参数args为取出方法的参数setUserDAO的参数为为一个UserDAO对象,而beanObject就是该类型。
test代码:
package com.l.service; import java.io.IOException; import org.junit.Test; import com.l.impl.UserDAOImpl; import com.l.model.User; import com.l.spring.BeanFactory; import com.l.spring.ClassPathXMLApplicationContext; public class UserServiceTset { @Test public void addTest() throws IOException, Exception{ BeanFactory factory = new ClassPathXMLApplicationContext(); UserService service = (UserService)factory.getBean("userService"); User u = new User(); service.add(u); } }
测试通过,从原理上了解IOC更好的开始学习spring
相关推荐
NULL 博文链接:https://ylxy3058.iteye.com/blog/2223489
Spring中ApplicationContext和beanfactory区别.rar
NULL 博文链接:https://lgd-java2eye.iteye.com/blog/756599
Spring的BeanFactory的接口的中文解释
NULL 博文链接:https://bjameng.iteye.com/blog/1468057
主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
spring之beanfactory 的一些基本知识与其关系使用
Spring注解驱动开发第41讲——Spring IOC容器创建源码解析(一)之BeanFactory的创建以及预准备工作(合起来整个过程)
文章目录Spring总结Spring容器控制反转(IoC)基于XML的IoC Spring总结 Spring容器 什么是Spring容器 从概念上讲:Spring 容器是 Spring框架的核心,是用来管理对象的...Spring最基本的接口就是BeanFactory, BeanFac
对BeanFactory的相关所有接口的功能的关键点进行了总结描述,中文版本
今天小编就为大家分享一篇关于spring中的BeanFactory与FactoryBean的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
NULL 博文链接:https://364232252.iteye.com/blog/2369489
主要给大家介绍了关于Spring中BeanFactory与FactoryBean接口的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
本篇文章主要介绍了Spring中BeanFactory解析bean详解 ,详细的介绍了使用BeanFactory对bean进行解析的实例,有兴趣的可以了解一下。
Spring教程 1 Spring框架概述 3 Spring是什么? 3 Spring的历史 4 Spring的使命(Mission Statement) 4 Spring受到的批判 4 Spring包含的模块 5 总结 6 Spring的IoC容器 6 用户注册的例子 7 面向接口编程 8 (用户...
Spring教程 1 名词解释 2 Spring框架概述 3 Spring是什么? 3 Spring的历史 4 Spring的使命(Mission Statement) 4 Spring受到的批判 4 Spring包含的模块 5 总结 6 Spring的IoC容器 6 用户注册的例子 7 ...
spring3中实例化BeanFactory的3中方法
Spring的IoC容器之BeanFactory[定义].pdf
一共近百道题与完整答案Spring框架的优点都有什么?...spring 中的BeanFactory与ApplicationContext的作用和区别?Spring如何实现资源管理?如何在web应用里面配置spring?。。。。。。 适合面试、学习、总结与复习.
BeanFactory是用于访问Spring Bean容器的根接口,是一个单纯的Bean工厂,也就是常说的IOC容器的顶层定义,各种IOC容器是在其基础上为了满