Spring学习笔记(一)IoC(XML部分)

Spring学习笔记(一)IoC(XML部分)

  学习Spring看的是上学堂马士兵老师的Spring2.5视频教程,里面用的Spring版本是2.5.6。前两天看完IoC部分的视频,在这里总结下笔记,留给以后用到Spring时回忆知识点。

  Spring Ioc教程里面分为两个部分:Spring IoC模拟和Spring IoC使用

Spring IoC模拟

  需求:需要一个增加用户的需求,增加用户的逻辑可能会在MySQL、SqlServer、Oracle中。

  设计(具体设计思想不阐述):实体类User(Model)、UserDAO(功能接口)、UserDAOImpl(UserDAO实现类)、Service(提供方法服务)

  

  图1 增加用户业务时序图

  在图1中。UserService增加用户的服务add()需要实现UserDAO接口的UserDAOImpl的save()方法,即在UserService中哟一个实例化的UserDAOImpl对象,继而,实例化UserService对象的实例化需要依赖于UserDAOImpl对象的注入。

 编写Beans.XML文件

  Spring的配置文件写在Beans.XML中。

 

<beans>
	<bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" />
	<bean id="userService" class="com.bjsxt.service.UserService" >
		<property name="userDAO" bean="u"/>
	</bean>
</beans>

 里面每一个bean代表一个实例化的对象,id为对象的名字,class代表对应的需要实例化的那个对象。property是当前类中的属性。bean="u"即这userDAO对象是id="u"的那个对象。

 编写BeanFactory接口和ClassPathXmlApplicationContext类

  在Spring中,Bean的读取是通过ClassPathXmlApplicationContext读取的。我们也来模拟一个。

private Map<String , Object> beans = new HashMap<String, Object>();
	
	
	//IOC Inverse of Control DI Dependency Injection
	public ClassPathXmlApplicationContext() throws Exception {
		SAXBuilder sb=new SAXBuilder();
	    
       //这一部分是beans.xml文件的读取
	    Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //构造文档对象
	    Element root=doc.getRootElement(); //获取根元素HD
	    List list=root.getChildren("bean");//取名字为disk的所有元素
	    for(int i=0;i<list.size();i++){
	       Element element=(Element)list.get(i);
	       String id=element.getAttributeValue("id");
	       String clazz=element.getAttributeValue("class");
	       Object o = Class.forName(clazz).newInstance();
	       System.out.println(id);
	       System.out.println(clazz);
	       beans.put(id, o);
	       
	       for(Element propertyElement : (List<Element>)element.getChildren("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);
	    	   System.out.println("method name = " + methodName);
	    	   
	    	   Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
	    	   m.invoke(o, beanObject);
	       }
	    } 
	}

上面代码中Map是模拟的Spring的管理池,每一个bean标签都实例化一个对象放入Map池中。IoC(Inversion of Control)控制反转,即原来的类,成员变量是我们进行管理,现在交付给Spring统一管理。

Spring IoC使用

环境搭建:

  • 需要spring.jar和commons-logging.jar
  • 在项目中增加beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
</beans>

bean的获取(得事先在beans.xml中配置相应的bean,参见IoC模拟部分的beans.xml代码)

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService service = (UserService)ctx.getBean("userService");

setter注入和constructor注入

  • 在模拟IoC的时候如果一个类中有一个成员变量是对象。那在实例化这个类的时候需要现实里话这个对象成员变量,然后将这个对象注入到这个类中,然后实例化,在模拟IoC部分使,如下面代码,属于setter注入(Setter Injection)
 <bean id="userService" class="com.bjsxt.service.UserService">
  	<!-- 
  	<property name="userDAO" ref="u" />
     另一种写法
  	 -->
  	 <constructor-arg>
  	   <ref bean="u"/>
  	 </constructor-arg>
  </bean>
  • 在constructor Injection中,由于累的构造函数可能会有若干个args(参数)。故有两种区分的方式
    • 有参数类型区分
    • 索引区分

bean的Scope:常用的有singleton(单例)、prototype

  • singleton是每一次调用相同的<bean>时都用第一次实例化的<bean>的对象
  • prototype则是每一次都new一个新的对象
  • prototype的方式跟struts2中的Action一样,struts1中使用的是singleton方式

集合注入

  • 在bean中有map、list等集合属性,为这些map、list中的属性注入值。这里参见Spring文档的示例即可,比较简单

自动装配(AutoWire)

  • 在bean中不知能需要注入的是哪一个bean。Spring会根据autowire设定的属性确定自动装配容器池中的那个bean
  • 注意1,在IoC方式中,autowire的使用很少,在annotation时才会用到。
  • 注意2,在autowire="byType"时,bean.xml中有多个相同类型的bean会抛异常

AutoWire之前:

<bean id="u" class="xx">
    <property name="UserDaoImpl">
        <ref bean="xxxx"></ref>
     </property>
</bean>

AutoWire之后:

<bean id="u" class="xx" autowire="byName">
</bean>

这里之列出了一个bean标签。需要额外的bean标签才能完成自动装配。

生命周期

  • lazy-init/default-lazy-init:
    • 延时启动,在内存不足的时候,或开启有大量的beans时需要经常启动server时才会用到
  • init-method,destory-method
    • 一般不会用到,常用的是Spring内部的连接池。
    • 注意,这两个方法只有在scope=singleton时才有用。scope=prototy时,虽然不会报错,但是不起作用

到这里,Spring IoC(XML)部分的知识点已经说完,这一部分不是很难,总体的逻辑就是,如何配置xml,是的Spring能够管理我们的对象。

posted on 2013-08-23 21:36  wenlonghor  阅读(349)  评论(0编辑  收藏  举报

导航