关闭

Spring快速上手+精解Spring之IoC原理

标签: springIoC
212人阅读 评论(0) 收藏 举报
分类:

一、Spring快速上手
1.Spring简介
1.1优势
可有效的把现有框架(如Struts和Hibernate)组织起来;
实现了真正意义上的面向接口编程,实现组件之间的高度解耦;
让使用Spring创建的应用尽可能少的依赖于它的APIs.
易于单元测试;
尽可能避免使用硬编码,代码可重用性高;
为数据存取提供了一个一致的框架。
1.2依赖注入(DI)和控制反转(IOC)
传统上,被调用者的实例都是由调用者创建,而在DI或IOC中,实例是由Spring框架中的容器创建(在容器
中配置判断实例类型,创建后注入调用者)
1.3面向切面编程(AOP)
横切代码:像日志代码这种分散在各处且与对象核心功能无关的代码。
OOP中,横切代码导致大量的代码重复,增加模块复用的难度。AOP解决了这种局限性。
AOP利用了一种称为“横切”的技术将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,将其
封装为一个可重用的模块,这个模块被命名为“切面”。
1.4日志
主要用来监控代码中变量的变化,Spring中一般应用Log4j框架。
2.Spring框架模块
2.1核心容器
Beans和Core模块:
Context模块:
Expression Language模块:
2.2数据访问/集成模块
JDBC模块:
ORM模块:
OXM模块:
JMS模块:
Transaction模块:
2.3Web模块
Web模块:
Servlet模块:
Struts模块:
Portlet模块:
2.4AOP和Instrumentation模块
AOP模块:
Instrumentation模块:
2.5Test模块
3.配置
3.1Spring和commons-logging开发包
src目录下创建applicationContext.xml文件

     <bean id="实例名" class="全限定类名">
       <property name="属性">
         <value>属性值</value>
       </property>
     </bean>

4.Spring的IoC容器
两种:BeanFactory和ApplicationContext
BeanFactory由org.springframework.beans.factory.BeanFactory接口定义,是基础类型的IoC容器;
ApplicationContext由org.springframework.context.ApplicationContext接口定义,以BeanFactory为基础
构建;
4.1BeanFactory及其工作原理
实际上是一个用于配置和管理Java类的内部接口,负责初始化各种Bean并调用他们的生命周期方法。
4.2BeanFactory接口包含的基本方法
Boolean containsBean(String name) :是否包含id为name的Bean
Object getBean(String name) :返回id为name的Bean
Object getBean(String name,Class requiredType) :返回id为name,类型为requiredType的Bean.
Class getType(String name) :返回id为name的Bean的类型
ApplicationContext是BeanFactory的子接口,也被称为应用上下文。提供了更多的附加功能,如对国际化的
支持等。一个非常重要的优势:当ApplicationContext容器初始化完成后,容器中所有的singleton Bean都被
实例化了(预初始化)。
ApplicationContext接口有3个实现类:
(1) ClassPathXmlApplicationContext:从类加载路径下的XML文件中获取上下文定义信息,创建
ApplicationContext实例;

    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");

(2)FileSystemXmlApplicationContext:从文件系统中的XML文件中获取上下文定义信息,创建
ApplicationContext实例;

    ApplicationContext context=new ClassPathXmlApplicationContext("d:/bean.xml");

(3)XmlWebApplicationContext:从Web系统中的XML文件中获取上下文定义信息,创建
ApplicationContext实例;
二、精解Spring之IoC原理
1.依赖注入的3种实现方式
1.1设值注入
IoC容器使用setter方法来注入被依赖的实例。(调用无参构造器或无参static工厂方法实例化bean之后,调
用该bean的setter方法,即可实现基于setter的DI)

     <bean id="u" class="com.dao.UserDaoImpl">
     </bean>
     <bean id="userService" class="com.service.UserServiceImpl">
     <!-- 将UserDaoImpl类的实例u注入到UserServiceImpl类的实例userService的userDao属性 -->
       <property name="userDao">
         <ref bean="u">
       </property>
     </bean>

1.2构造方法注入
IoC容器使用构造方法来注入被依赖的实例。(基于构造器的DI通过调用带参数的构造方法来实现,每个参数
代表着一个依赖)

    //定义构造方法
    public UserServiceImpl(UserDao userDao){
       super();
       this.userDao=userDao;
    }
    <bean id="u" class="com.dao.UserDaoImpl">
    </bean>
    <bean id="userService" class="com.service.UserServiceImpl">
    <!-- 将UserDaoImpl类的实例u注入到UserServiceImpl类的实例userService的userDao属性 -->
       <constructor-arg index="0">
         <ref bean="u">
       </constructor-arg>
    </bean>

!!当userService实例创建完成后,u实例也已经注入其中了。
如果构造函数有多个参数,则配置《constructor-arg》元素时,必须指定每个参数的位置索引。参数按顺序指
定,第一个参数的索引值是“0”。
!!设值注入是先通过无参构造方法创建一个Bean实例,然后再调用对应的setter方法来注入依赖关系。
构造注入则是直接调用有参的构造方法来创建Bean实例,实例创建完成后,依赖关系也已经注入完毕了。
1.3接口注入
需要类实现特定的接口或继承特定的类(必须依赖他们)。这也意味着侵入性(Apache开源的Avalon和EJB容
器属于这一类)。!!Spring不支持接口注入
2.设值注入和构造方法注入两种方式的比较
2.1设值注入的优点
直观、自然;
依赖关系比较复杂时,构造方法注入会导致构造方法相当庞大(需在构造方法中设定所有依赖关系),此时使
用设置方法注入更为简洁。
2.2设值注入缺点
需要对每个需要注入的类属性定义public setter方法,容易破坏类的状态和行为。
2.3构造注入优点
很好的响应了Java的设计原则之一——“构造期间即创建一个完整、合法的对象”;
避免了繁琐的setter方法的编写,所有依赖关系都在构造方法中设定,依赖关系集中体现,更加易读;
关联关系仅在构造方法中表达,只有组件创建者需要关心组件内部的依赖关系。
2.4构造注入缺点
出现错误很难查;
继承中,构造方法不会自动继承下去,必须手动完成;
很难处理一些特殊情况(如:不是必须的而是可选择的属性(部分原因是Java不能在构造方法中设置默认
值),循环的依赖关系)。
!!对一般项目开发,以设值注入为主,辅之以构造注入为补充。
3.Spring IoC简单模拟实现
3.1Java反射机制简介
反射是Java语言特有的。
3.2使用JDOM读取XML信息
所需JAR包:jdom.jar

      //test.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <HD>
         <disk name="C">
           <capacity>20G</capacity>
           <directories>100</directories>
           <files>123456</files>
         </disk>
         <disk name="D">
           <capacity>300G</capacity>
           <directories>999</directories>
           <files>987654</files>
         </disk>
      </HD> 
       import java.util.*;
       import org.jdom.*;
       import org.jdom.input.SAXBuilder;
       public class JdomSample {
          public static void main(String[] args) throws Exception{   
            **SAXBuilder sb=new SAXBuilder();
            Document doc=sb.build(JdomSample.class.getClassLoader()
            .getResourceAsStream("test.xml"));** //构造文档对象 
            Element root=doc.getRootElement(); //获取根元素HD
            List list=root.getChildren("disk");//取名字为disk的所有元素
            for(int i=0;i<list.size();i++){
            Element element=(Element)list.get(i);
            String name = element.getAttributeValue("name");
            String capacity=element.getChildText("capacity");//取disk子元素capacity的内容
            String directories=element.getChildText("directories");
            String files=element.getChildText("files"); 
           //打印输出
             System.out.println("磁盘信息:");
             System.out.println("分区盘符:"+name);
             System.out.println("分区容量:"+capacity);
             System.out.println("目录数:"+directories);
             System.out.println("文件数:"+files);
             System.out.println("-----------------------------------");    
            }  
         }
       } 
         .getRootElement();.getChildren(" ");.getAttributeValue("name");
         .getChildText(" ")
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7661次
    • 积分:674
    • 等级:
    • 排名:千里之外
    • 原创:47篇
    • 转载:2篇
    • 译文:0篇
    • 评论:0条