Spring IOC的使用

  控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转,目的是为了获得更好的扩展性和良好的可维护性。所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。

实例化Spring容器常用的两种方式:

方法一:

  在类路径下寻找配置文件来实例化容器

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});

  可以在整个类路径中寻找xml文件

  • 通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下
  • classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。

方法二:

  在文件系统路径下寻找配置文件来实例化容器  

ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\beans.xml“});

  当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:   

 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
 Girl girl =(Girl)ctx.getBean("girl"); 

 三种实例化bean的方式

  1.使用类构造器实例化(默认无参数)

<bean id=“personService" class="cn.itcast.bean.impl.PersonServiceImpl"/>

  2.使用静态工厂方法实例化(简单工厂模式)

<bean id="personService" class="com.itcast.factory.PersonServiceFactory"    factory-method="createPersonService" />

public class PersonServiceFactory {
      public  static PersonService  createPersonService(){
               return new PersonServiceImpl();
      }
}

  3.使用实例工厂方法实例化(工厂方法模式):

<bean id=“personServiceFactory" class="com.itcast.factory.PersonServiceFactory"/>
<bean id="personService" factory-bean=“personServiceFactory"
factory-method="createPersonService" />
public class PersonServiceFactory {
       public  PersonService createPersonService(){
                     return new PersonServiceImpl();
       }
}

Bean的作用域

  • singleton(默认值)在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:<bean id="xxx" class="cn.itcast.OrderServiceBean" lazy-init="true"/>如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:<beans default-lazy-init="true“ ...>
  • prototype.允许bean可以被多次实例化(使用一次就创建一个实例)
  • request
  • session
  • global session(Portlet规范将portlet定义为一种“基于Java技术的web组件,由处理请求和生成动态内容的portlet容器管理”)

指定Bean的初始化方法和销毁方法

  Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。

 <bean id=“foo” class=“...Foo” init-method=“setup” destory-method=“teardown”/>
  • 当bean被载入到容器的时候调用setup
  • 当bean从容器中删除的时候调用teardown(scope= singleton有效)

依赖注入

  • 使用构造器注入
  • 使用属性setter方法注入
  • 使用Field注入(用于注解方式)

  注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。依赖注入--手工装配:手工装配依赖对象,在这种方式中又有两种编程方式

  • 在xml配置文件中,通过在bean节点下配置
  • 在java代码中使用@Autowired或@Resource注解方式进行装配

通过setter方法注入依赖

  <bean>元素的< property >子元素指明了使用它们的set方法来注入。可以注入任何东西,从基本类型到集合类,甚至是应用系统的bean。

1.简单bean配置:配置bean的简单属性,基本数据类型和String。

<bean id="personService"   class="com.itcast.bean.impl.PersonServiceImpl">
               <!-- 基本类型,string类型 -->
              <property name="age" value="20"></property>
              <property name="name" value="张无忌"></property>                       
</bean>

2.引用其它bean

<bean id="person" class="com.itcast.bean.Person" />
<bean id="personService" class="com.itcast.bean.impl.PersonServiceImpl">
      <!-- 引用类型 -->
      <property name="person" ref="person" />
</bean>

3.内部bean

<bean id="personService" class="com.itcast.bean.impl.PersonServiceImpl">
          <!-- 内部bean注入 -->
         <property name="personClass">
                <bean class="com.itcast.bean.PersonClass" />
         </property>
</bean>

  这种方式的缺点是你无法在其它地方重用这个personClass实例,原因是它是专门为personService而用。

4.装配集合

  若bean的属性是集合类型,按如下处理:

  A.装配List和数组:

<!-- 装配list -->
<property name="lists">
            <list>
                <value>list1</value>
                <value>list2</value>
                <ref bean="person"/>
            </list>
</property>
<!-- 装配数组 -->
<property name="obj">
           <list>
                <value>obj1</value>
                <value>obj2</value>
                <ref bean="person"/>
           </list>
</property>

  B. 装配set:

<!-- 装配set -->
<property name="sets">
           <set>
                <value>set1</value>
                <value>set2</value>
                <ref bean="person"/>
           </set>
/property>

   C. 装配map:

<!-- 装配map-->
<property name="maps">
             <map>
                  <entry key="01">
                          <value>map01</value>
                  </entry>
                  <entry key="02">
                          <value>map02</value>
                  </entry>
             </map>
</property>

  D.装配Properties:

<!--装配Properties  -->
<property name="props">
           <props>
             <prop key="01">prop1</prop>
             <prop key="02">prop2</prop>
           </props>
</property>
 

  E.设置null:

<!-- 装配null -->
<property name="listnull">
           <null/>
</property>

  F.通过参数的顺序:

<constructor-arg index="0">
      <value>张三</value>
</constructor-arg>
<constructor-arg index="1">
       <value>56</value>
</constructor-arg>

  G.通过参数的类型:

<!-- 通过参数的类型 -->
<constructor-arg type="java.lang.Integer">
              <value>56</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
              <value>张三</value>
</constructor-arg>

注解方式

  在java代码中使用@Autowired或@Resource注解方式进行装配的前提条件是。

  1.引入context命名空间  需要在xml配置文件中配置以下信息: 

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">
       <context:annotation-config/>
</beans>

  2、在配置文件中添加context:annotation-config标签

 <context:annotation-config/>

  这个配置隐式注册了多个对注释进行解析处理的处理器AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,

RequiredAnnotationBeanPostProcessor

  注: @Resource注解在spring安装目录的libj2eecommon-annotations.jar

  在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。

@Autowired
private PersonDao  personDao;//用于字段上
@Autowired
public void setPersonDao(PersonDao personDao) {  //用于属性的set方法上
         this.personDao = personDao;
}

  @Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。

@Autowired(required=false)
private PersonDao  personDao;//用于字段上
@Autowired(request=false)
public void setPersonDao(PersonDao personDao) {  //用于属性的set方法上
         this.personDao = personDao;
}

  @Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上.

  @Resource注解默认按名称装配。名称可以通过@Resource的name属性指定,如果没有指定name属性,1)当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象;2)当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象

@Resource(name="personDao")
private PersonDao personDao;;//用于字段上
@Resource(name="personDao")
public void setPersonDao(PersonDao personDao) {//用于属性的set方法上
       this.personDao = personDao;
}

  后一种相当于xml配置文件中的   

<property name=“personDao" ref="personDao" />

  注意:如果没有指定name属性,并且按照默认的名称找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。

  spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:

  1.引入context命名空间  需要在xml配置文件中配置以下信息:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">
       <context:component-scan base-package="cn.itcast"/>
</beans>

  2.在配置文件中添加context:component-scan标签      

<context:component-scan base-package="cn.itcast"/>

       其中base-package为需要扫描的包(含子包)。注:

  1. 在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor 和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。
  2. 功能介绍
  • @Service用于标注业务层组件、
  • @Controller用于标注控制层组件(如struts中的action)、
  • @Repository用于标注数据访问组件,即DAO组件。
  • 而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
原文地址:https://www.cnblogs.com/wxgblogs/p/5802236.html