Spring IOC的配置与注入

Spring的体系结构

这里写图片描述
整个Spring框架按其所属功能可以划分为五个主要模块,这五个模块几乎为企业应用提供了所需的一切,从持久层、业务层到表现层都拥有相应的支持,这就是Spring为什么是一站式框架。IoC和AOP是Spring的核心。

-核心模块(Core Container)

  • pring的核心模块实现了IoC的功能,它将类和类之间的依赖从代码中脱离出来,用配置的方式进行依赖关系描述。 由IoC容器负责类的创建,管理,获取等。BeanFactory接口是Spring框架的核心接口,实现了容器很多核心的功能。

  • Context模块构建于核心模块之上,扩展了BeanFactory的功能,包括国际化,资源加载,邮件服务,任务调度等多项功能。ApplicationContext是Context模块的核心接口。

  • 表达式语言(Expression Language)是统一表达式语言(EL)的一个扩展,支持设置和获取对象属性,调用对象方法,操作数组、集合等。使用它可以很方便的通过表达式和Spring IoC容器进行交互。

-AOP模块

  • Spring AOP模块提供了满足AOP Alliance规范的实现,还整合了AspectJ这种AOP语言级的框架。通过AOP能降低耦合。

-数据访问集成模块(Data Access/Integration )
该模块包括了JDBC、ORM、OXM、JMS和事务管理

  • 事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和声明性的事务管理。

  • JDBC模块:提供了一个JBDC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。

  • ORM模块:提供与流行的“对象-关系”映射框架的无缝集成,包括Hibernate、JPA、MyBatis等。而且可以使用Spring事务管理,无需额外控制事务。

  • OXM模块:提供了一个对Object/XML映射实现,将java对象映射成XML数据,或者将XML数据映射成java对象,Object/XML映射实现包括JAXB、Castor、XMLBeans和XStream。

  • JMS模块:用于JMS(Java Messaging Service),提供一套 “消息生产者、消息消费者”模板用于更加简单的使用JMS,JMS用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

-Web模块

  • 该模块建立在AoolicationContext模块之上,提供了Web应用的功能。如文件上传、FreeMarker等。
  • Spring可以整合Struts2等MVC框架。Spring自己提供了MVC框架Spring MVC。

-测试模块

  • Spring可以用非容器依赖的编程方式进行几乎所有的测试工作,支持JUnit和TestNG等测试框架。

ApplicationContext & BeanFactory

  • Spring通过一个配置文件描述Bean与Bean之间的依赖关系,通过Java语言的反射技术能实例化Bean并建立Bean之间的依赖关系。Spring的IoC容器在完成这些底层工作的基础上,还提供了bean实例缓存、生命周期管理、事件发布,资源装载等高级服务
  • BeanFactory是Spring最核心的接口,提供了高级IoC的配置机制。ApplicationContext建立在BeanFactory的基础上,提供了更多面向应用的功能。我们一般称BeanFactory为IoC容器,ApplicationContext为应用上下文,也称为Spring容器。

  • BeanFactory是Spring框架的基础,面向Spring本身,ApplicationContext面向使用Spring框架的开发者,几乎所有的应用我们都直接使用ApplicationContext而非底层的BeanFactory。

BeanFactory(过时)

BeanFactory是一个类工厂,和传统的类工厂不同,传统的类工厂仅负责构造一个类或几个类的实例。而BeanFactory可以创建并管理各种类的对象,Spring称这些被创建和管理的Java对象为Bean。

BeanFactory是一个接口,Spring为BeanFactory提供了多种实现,最常用的就是XmlBeanFactory。

BeanFactory接口最主要的方法就是getBean(String beanName),该方法从容器中返回指定名称的Bean。

BeanFactory接口的功能通过其他实现它的接口不断扩展。

ApplicationContext

ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要编程方式来实现,ApplicationContext中可以通过配置的方式来实现。

ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中加载配置文件。

和BeanFactory初始化相似,ApplicationContext初始化也很简单。

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

ApplicationContext的初始化和BeanFactory初始化有一个重大的区别,BeanFactory初始化容器时,并未初始化Bean,第一次访问Bean时才创建。而ApplicationContext则在初始化时就实例化所有的单实例的Bean。因此ApplicationContext的初始化时间会稍长一点。

PS : web开发中,使用applicationContext. 在资源匮乏的环境可以使用BeanFactory.

Spring的IOC例子

1、 导包

这里我们只是做IoC的操作,所以只需要导入核心模块里的jar包,因为spring中并没有日志相关的jar包,所以我们还需要导入log4j和commons-logging
这里写图片描述

2、创建一个对象

public class User {
    private String name;
    private Integer age;
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

3、配置注册对象到容器

1、创建一个xml配置文件,放在src目录下,名字可以随便取(建议applicationContext.xml)
2、导入约束--beans(具体怎么导入,自行了解)
3、配置 applicationContext.xml 要创建的类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns="http://www.springframework.org/schema/beans"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">

<--要创建的类-->
<bean name="user" class="cdn.pngyul.com.User"></bean>
</beans>

4、代码测试

public class demo {
    @Test
    public void fun1() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) ac.getBean("user");
        System.out.println(user);
    }
}

Bean元素

  • bean元素:使用该元素描述需要Spring容器管理的对象。
  • class属性:被管理对象的完整类名
  • name属性:给被管理的对象取个名字,获得对象时根据该名字获取对象,可以重复,可以使用特殊字符,尽量使用name属性
  • id属性:与name属性一样,但名字不能重复,不能使用特殊字符
  • scope属性:
 singleton(默认值):单例对象.被标识为单例的对象在spring容器中只会存在一个实例
 prototype:多例原型.被标识为多例的对象,每次再获得才会创建.每次创建都是新的对象.
           整合struts2时,ActionBean必须配置为多例的.
 request:web环境下.对象与request生命周期一致.
 session:web环境下,对象与session生命周期一致.
  • bean的生命周期属性
init-method:配置一个方法作为生命周期初始化方法,spring会在对象创建之后立即调用
destory-method:配置一个方法作为生命周期的销毁方法,spring容器在关闭并销毁所有
 容器中的对象之前调用.

Bean的实例化方式

1、空参构造方式

<bean name="user" class="cdn.pngyul.com.User"></bean>

2、使用静态工厂方法实例化

public class CreateUser {
    public static User createUser() {
        System.out.println("静态工厂创建User");
        return new User();
    }
}
//工厂类方法是静态的,可以不用创建工厂类实例直接使用。
<bean name="user2" class="cdn.pngyul.com.CreateUser"
        factory-method="createUser">
</bean>

3、使用实例工厂方法实例化

public class CreateUser {
    public User createUser2() {
        System.out.println("实例工厂创建User");
        return new User();
    }
}
//工厂方法是非静态的,即必须实例化工厂类后才能调用工厂方法。
<bean name="userFactory" class="cdn.pngyul.com.CreateUser"></bean>
<bean  name="user3" factory-bean="userFactory" factory-method="createUser2"></bean>

Bean的属性注入(注入方式)

1、set方法注入(常用)

//属性注入要求Bean提供一个默认的构造方法,并为需要注入的属性提供对应的set方法。Spring调
Bean的默认构造方法创建对象,然后通过反射的方式调用set方法注入属性。 
<bean name="user" class="cdn.pngyul.com.User">
     <property name="name" value="zhangsan"></property>
     <property name="age" value="25"></property>
     <property name="car" ref="car"></property>
</bean>

2、构造函数注入

<bean name="user" class="cdn.pngyul.com.User">
    <!-- name: 构造函数的参数名 
         type: 构造函数的参数类型 
         index:构造函数的参数索引,也就是说"第几个参数"
     -->
    <constructor-arg name="name" value="lisi" type="java.lang.String"
       index="0"></constructor-arg>
</bean>

3、p名称空间注入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd ">

    <!-- p名称空间,需要提供对应的set方法 -->
    <!-- 1、导入P名称空间 xmlns:p="http://www.springframework.org/schema/p"
    2、使用p:属性完成注入
          |-值类型:p:属性名="值"
          |-对象类型:p:属性名-ref="bean名称"
    -->
    <bean name="user" class="cdn.pngyul.com.User" p:age="20" p:name="jack" 
          p:car-ref="car"> 
    </bean>
</beans>

4、spel注入

<bean name="user" class="cdn.pngyul.com.User">
    <!--spel:Spring Expession Language spring表达式语言-->
    <property name="name" value="#{user.name}"></property>
    <property name="age" value="#{user1.age}"></property>
    <property name="car" ref="car"></property>
</bean>

复杂类型注入

//首先创建一个类,包括各种集合类型
public class Collection {
        private String[] arr;
        private List<String> list; 
        private Set<String> set; 
        private Map<String,String> map; 
        private Properties properties;
        public void setArr(String[] arr) {
            this.arr = arr;
        }
        public void setList(List<String> list) {
            this.list = list;
        }
        public void setSet(Set<String> set) {
            this.set = set;
        }
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
        @Override
        public String toString() {
            return "Collection [arr=" + Arrays.toString(arr) + ", list=" + list + ", set=" + set + ", map=" + map
                    + ", properties=" + properties + "]";
        }
}
    <bean name="collections" class="cdn.pngyul.com.Collection">
        <!-- 配置一般数组 -->
        <!-- 如果数组中只准备注入一个值/对象,直接使用value|ref即可 
             <property name="arr" value="10"></property>
        -->
        <property name="arr">
            <array>
                <value>zhangsan</value>
                <ref bean="user" />
            </array>
        </property>

        <!--配置list集合 -->
        <!-- 如果list中只准备注入一个值/对象,直接使用value|ref即可 
             <property name="list" value="tom"></property>
        -->
        <property name="list">
            <list>
                <value>zhangsan</value>
                <value>lisi</value>
            </list>
        </property>

        <!--配置set集合 -->
        <property name="set">
            <set>
                <value>zhangsan</value>
                <value>kisi</value>
            </set>
        </property>

        <!--配置map集合 -->
        <property name="map">
            <map>
                <entry key="TV" value="2000"></entry>
                <entry key="computer" value="7000"></entry>
            </map>
        </property>

        <!--配置properties类型 -->
        <property name="properties">
            <props>
                <prop key="pro1">one</prop>
                <prop key="pro2">two</prop>
            </props>
        </property>
    </bean>

PS:本文参考个人博客—-春水上行 自行总结,如有侵权,请联系本人修改或删除。

猜你喜欢

转载自blog.csdn.net/PNGYUL/article/details/81557608