spring学习

本文为学习笔记,参考传智播客spring2.5视频

一、控制反转(IOC):应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用本身转移到了外部容器,控制权的转移就是所谓的控制反转。

二、依赖注入(DI):在运行期,由外部容器动态地将依赖对象注入到组件中。网上看到的有比较容易理解的对依赖注入的描述:“平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做。”

依赖注入有手工装配、自动装配两种形式。其中在实际使用中使用手工装配,自动装配会发生一些不可控现象。手工装配常用的有三种方式:

1、使用属性的setter方法注入(要求对要注入的属性必须设置set方法)

  *基本类型对象注入:

    <bean id="personService" class="com.ushareit.springMaven.service.impl.PersonServiceBean">
      <property name="name" value="ushareit"></property>
      <property name="id" value="34"></property>
    </bean>

  *注入其他bean有两种方式:

    1、ref方式

     <bean id="personDao" class="com.ushareit.springMaven.dao.impl.PersonDaoBean"></bean>
       <bean id="personService" class="com.ushareit.springMaven.service.impl.PersonServiceBean">
      <property name="personDao" ref="personDao" ></property>
     </bean>

    2、使用内部bean

     <bean id="personService" class="com.ushareit.springMaven.service.impl.PersonServiceBean">
      <property name="personDao">

        <bean class = "com.ushareit.springMaven.dao.impl.PersonDaoBean"></bean>

      </property>
     </bean>

  *集合类型Set的注入:

    <property name="sets">
      <set>
        <value>第一个</value>
        <value>第二个</value>
        <value>第三个</value>
      </set>
    </property>

  *列表类型List注入: 

      <property name="lists">
      <list>
        <value>list1</value>
        <value>list2</value>
        <value>list3</value>
      </list>
      </property>

  *Property类型注入:

    <property name="properties">
      <props>
        <prop key="key1">value1</prop>
        <prop key="key2">value2</prop>
        <prop key="key3">value3</prop>
      </props>
    </property>

  *Map类型注入:

      <property name="maps">
      <map>
        <entry key="key-1" value="value-1"></entry>
        <entry key="key-2" value="value-2"></entry>
        <entry key="key-3" value="value-3"></entry>
      </map>
    </property>

2、使用构造器注入

  使用<constructor-arg>标签

<bean id="personDao" class="com.ushareit.springMaven.dao.impl.PersonDaoBean"></bean>
<bean id="personService" class="com.ushareit.springMaven.service.impl.PersonServiceBean">
    <constructor-arg index="0" type="com.ushareit.springMaven.dao.PersonDao"
              ref="personDao"></constructor-arg>
    <constructor-arg index="1" value="茄子快传"></constructor-arg>
</bean>

  并且需在构造器中对要注入的属性赋值。

public class PersonServiceBean implements PersonService {
    private PersonDao personDao;
    private String name;
    public PersonServiceBean(PersonDao personDao, String name) {
        this.personDao = personDao;
        this.name = name;
    }
    public void save() {
        personDao.add();
        System.out.println(name);
    }
}

3、使用Field注入(用于注解方式)

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

三、使用spring的好处:

  *降低组件之间的耦合度,实现软件各层之间的解耦。controller--->service--->dao

  *可以使用spring容器提供的各种服务。如JMS服务、事务管理服务、spring core核心服务、持久化服务、其他服务。

  *容器提供单例模式支持,开发人员无需自己再手动实现。

  *采用AOP技术,很容易实现权限拦截、运行期监控等功能。

  *使用众多辅助类,加速应用开发,如JdbcTemplate。

  *对主流应用框架提供了很好集成支持,如JPA、hibernate、Struts等。 

四、实例化spring容器常用的两种方式:

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

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

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

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

  注:spring的配置文件可以指定多个,可以通过string数组引入

五、面向接口编程的思想

  A s = new B();

  一个对象实例只能赋值给与它类型相同的引用、或者父类(包括接口)的引用。

  B是A的实现类,所以B的实例可以赋值给A的引用。

  实例:确实的对象;引用:指向某一对象的名字。  

  耦合度:一个类(或者对象)对另一个类(或者对象)的依赖。指的是软件模块相互之间的关联,耦合度越高,这就说明软件的独立性越差。比方说,一个模块出现了问题,就可能牵连其他模块,导致其他模块的功能也不能正常运行。

   s这个对象具有A接口规定的一切方法(B类里强制必须实现的)。

       这样C、D、E、F类也可以实现A接口,如果想替换成C、D、E、F就很简单了,调用的时候还是用A接口规定的那些方法。

   结合一些动态载入(例如spring的xml配置可以动态生成类),不会耦合了。

 六、三种实例化bean的方式

  1、使用类构造器实例化(约占90%)

<bean id="personService" class="cn.ushareit.service.impl.PersonServiceBean"></bean>

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

<bean id="personService2" class="cn.ushareit.service.impl.PersonServiceBeanFactory" factory-method="createPersonServiceBean"></bean>
public class PersonServiceBeanFactory {
    public static PersonServiceBean createPersonServiceBean(){
       return new PersonServiceBean();
    }
}

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

<bean id="personServiceFactory" class="cn.ushareit.service.impl.PersonServiceBeanFactory"></bean>
    <bean id="personService3" factory-bean="personServiceFactory" factory-method="createPersonServiceBean2"></bean>
public class PersonServiceBeanFactory {
    public PersonServiceBean createPersonServiceBean2(){
        return new PersonServiceBean();
    }
}

七、bean的作用域(scope属性)

* singleton

  在每个Spring IOC容器中一个bean定义只有一个对象实例,相当于是单例模式。默认情况下会在容器启动时初始化bean。但我们可以指定bean节点的lazy_init="true"来延迟初始化bean,这时候,只有第一次获取bean才会初始化bean。如:<bean id="personService" class="cn.ushareit.service.impl.PersonServiceBean" lazy_init="true"></bean>。

  如果想对所有bean都使用延迟初始化,可以在根节点beans设置default-lazy-init="true",如下<beans default-lazy-init="true"...>

* prototype

  每次从容器获取bean都是新对象,即new。

 八、指定bean的初始化方法和销毁方法

  1、对于scope="singleton"的情况,在spring容器初始化的时候,bean就被初始化了。

  2、对于scope="prototype"的情况,只有在spring容器初始化完成后,调用getBean方法的时候,bean才被初始化。

  3、如果想保持spring容器中的bean是单例,还想延迟初始化bean,即在第一次获取bean的时候才初始化bean,就要靠lazy-init="true"(或default-lazy-init="true"全局)来控制。

posted @ 2015-11-18 17:33  达摩克利斯之剑  阅读(184)  评论(0编辑  收藏  举报