spring笔记

淺唱寂寞╮ 提交于 2020-01-08 05:38:10

Spring是什么

开源的,用来简化企业级应用开发的应用开发框架。

简化开发: Spring框架对常用的api都做了封装,比如:对jdbc就做了一套 封装(Spring Jdbc),使用SpringJdbc访问数据库, 就不再需要考虑如 何获取连接与关闭连接等操作了。

解耦: Spring帮我们管理对象之间的依赖关系(对象之间的耦合度降低了), 这样软件的维护性得到提高。

集成其它框架:Spring可以很好地和其它的一些框架进行集成,这样,使用 这些框架就更方便了。

Spring容器

(1)什么是Spring容器?

Spring框架中的一个核心模块,用来管理对象。

注:

管理对象:对象的创建、销毁、初始化等等操作,以及对象之间的依赖关系。

(2)如何启动Spring容器?

step1.导包。

在pom文件中

<dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-webmvc</artifactId>

    <version>3.2.8.RELEASE</version>

</dependency>

step2.添加Spring配置文件。

配置一个xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" 
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context" 
 5     xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
 6     xmlns:jee="http://www.springframework.org/schema/jee" 
 7     xmlns:tx="http://www.springframework.org/schema/tx"
 8     xmlns:aop="http://www.springframework.org/schema/aop" 
 9     xmlns:mvc="http://www.springframework.org/schema/mvc"
10     xmlns:util="http://www.springframework.org/schema/util"
11     xmlns:jpa="http://www.springframework.org/schema/data/jpa"
12     xsi:schemaLocation="
13         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
14         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
15         http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
16         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
17         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
18         http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
19         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
20         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
21         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
22     
23         
24 </beans>

 step3.启动容器。

String config = "applicationContext.xml";//字符串为Spring配置文件的全名
/**
* ApplicationContext接口(声明了容器的一些方法)
* ClassPathXmlApplicationContext类(实现了上述接口,
* 该类会依据类路径去查找配置文件然后启动容器)
*/
ApplicationContext ac = new ClassPathXmlApplicationContext(config);

(3)如何创建对象?

1)方式一 无参构造器

step1.为类添加无参构造器或者直接使用缺省构造器。

step2.在配置文件当中,添加bean元素。

<bean id="" class=""/>

bean指的是有容器管理的对象,id:要求唯一(注早期版本用的是name),class:要求写类的完整名字(全限类名)

        <!-- 使用无参构造器来创建对象 -->
        <bean id="apple" class="first.Apple"/>

step3.启动容器,调用容器提供的一个方法(getBean)。

/**
 * getBean方法的第一个参数时bean的id或者时bean的name,
 * 第二个方法
 */
 Apple A = ac.getBean("apple", Apple.class);

2) 方式二 静态工厂方法

<!-- 使用静态工厂方法创建对象
factory-method:指定一个静态方法(容器会调用该类的这个静态方法来创 建对象)=
相当于:Calender c = Clender.getInstance()-->
<bean id="ca" class="java.util.Calendar"factory-method="getInstance"/>

3) 方式三 实例工厂方法

<!-- 使用实例工厂方法创建对象,
actory-method:指定一个实例方法(容器会调用该实例的指定方法来创建对象)
factory-bean:指定要调用的对象的id
相当于:调用了GregorianCalendar对象的getTime方法 -->
<bean id="time" factory-bean="ca" factory-method="getTime"/>

(4)作用域(scope)

1)默认情况下(默认作用于为singleton),对于某个bean元素,容器只会创 建一个实例。

<bean id="bs" class="basic.ScopeBean" scope="singleton"/>
ScopeBean sc1 = ac.getBean("bs", ScopeBean.class);
ScopeBean sc2 = ac.getBean("bs", ScopeBean.class);
System.out.println(sc1==sc2);//------true-----

2)如果将作用域设置为"prototype",容器会创建多个实例。

<bean id="bs" class="basic.ScopeBean" scope="prototype"/>
ScopeBean sc1 = ac.getBean("bs", ScopeBean.class);
ScopeBean sc2 = ac.getBean("bs", ScopeBean.class);
System.out.println(sc1==sc2);//------false-------

(5)生命周期相关的两个方法

1)初始化

使用init-method属性指定初始化方法。

2)销毁

使用destroy-method属性指定销毁方法。

注意:只有作用域为singleton时,销毁方法才会执行。

 

    <!-- 
    init-method:指定初始化方法名
    destroy-method:指定销毁方法名
    注意:只有作用域为singleton(单例),销毁方法才会执行,
     -->
    <bean id="mb1" class="basic.MessageBean" init-method="init" 
    destroy-method="destroy" scope="prototype"/>        

 

 

 

(6)延迟加载(lazy-init)

1)默认情况下(lazy-init=”true”)

容器启动之后,会将所有作用域为singleton的bean先创建好。

 

    <!-- lazy-init:如果值为true,表示延迟加载 -->
    <bean id="sb1" class="basic.ScopeBean" lazy-init="true"/>

 

 

 

 

2)开启延迟加载后(lazy-init=”false”)

 

容器启动之后,对于作用域为singleton的bean,不再创建(当调用getBean 方法时才会创建)

 

IOC和DI

1)什么是IOC (Inversion Of Controll 控制反转)?

对象之间的依赖关系由容器来建立。

2)什么是DI(Dependency Injection 依赖注入)?

容器通过调用set方法或者构造器来建立对象之间的依赖关系。

注:

IOC是目标,DI是手段。

3)依赖注入的两种方式

方式一 set方法注入

step1. 添加set方法(在要注入的类中添加)。

step2. 在配置文件当中,使用<property>来配置set方法注入。

step3. 启动容器,调用getBean方法。

方式二 构造器注入

step1. 添加相应的构造器

step2. 在配置文件当中,使用<constructor-arg>来配置构造器注入。

step3. 启动容器,调用getBean方法。

 

4) 自动装配

在配置文件当中,不用告诉容器采用哪种注入方式也不用告诉容器被注入的 bean的id,有容器依据某些规则,自动建立对象之间的依赖关系,通过byName时被注入的id必须与注入的set方法名字一致

a.容器默认情况下,是不会自动装配的。

b.可以让容器依据某些规则,自动建立对象之间的依赖关系

(仍然需要调用set方法或者构造器)。

注:自动装配建议少用(配置文件虽然简化了,但可读性变差,而且容易出错),如果要使用,建议使用byName。

值的注入

注入基本类型的值

使用value属性

name与方法中对象的名一致,value的值的类型与对象的类型一致

<bean id="teacher" class="value.Teacher">
<property name="name" value="Hille"/>
<property name="age" value="85"/>
</bean>

注入集合类型的值

1) 方式一  直接注入

注入List(值可以重复):

<!-- 注入集合类型的值 -->
<property name="interest">
    <list>
    <value>吃饭</value>
    <value>睡觉</value>
    <value>敲代码</value>
    </list>
</property>

 

注入set:(值不能重复,如果有重复的值,只会注入一个)

<property name="city">
    <set>
        <value>北京</value>
        <value>郑州</value>
        <value>广州</value>
    </set>
</property>

 

注入map的值:(key的值不能重复,如果重复,后一个会把前一个的的value给顶掉)

<property name="score">
    <map>
        <entry key="英语" value="50"/>
        <entry key="语文" value="60"/>
        <entry key="数学" value="70"/>
        <entry key="生物" value="80"/>
        <entry key="化学" value="90"/>
    </map>
</property>

 

注入Property的值:

<property name="db">
    <props>
      <prop key="username">Sally</prop>
      <prop key="password">123456</prop>
    </props>
</property>

2) 方式二 引用的方式注入

注入List

 

注入set

<util:set id="cityBean">
    <value>北京</value>
    <value>郑州</value>
    <value>广州</value>
    <value>广州</value>
</util:set>

<bean id="t2" class="value.Teacher">
    <property name="city" ref="cityBean"/>
</bean>

 

注入map

<util:map id="scoreBean">
    <entry key="英语" value="50"/>
    <entry key="语文" value="60"/>
    <entry key="数学" value="70"/>
    <entry key="生物" value="80"/>
    <entry key="化学" value="90"/>
</util:map>

<bean id="t2" class="value.Teacher">
    <property name="score" ref="scoreBean"/>
</bean>

 

注入properties

<util:properties id="dbBean">
    <prop key="username">Sally</prop>
    <prop key="password">123456</prop>
</util:properties>

<bean id="t2" class="value.Teacher">
    <property name="db" ref="dbBean"/>
</bean>

 

读取properties文件

<bean id="t2" class="value.Teacher">
    <property name="db" ref="config"/>
</bean>
ClassPathXmlApplicationContext cptx = new ClassPathXmlApplicationContext("value.xml"); Properties p = cptx.getBean("config", Properties.class); System.out.println(p);

Spring表达式

读取bean的属性值或者读取集合类型的

<bean id="stu1" class="value.Teacher"><!-- 这个方法中必须有对应的get方法 -->
    <property name="name" value="Hille"/>
    <property name="interest">
        <list>
            <value>吃饭</value>
            <value>睡觉</value>
        </list>
    </property>
    <property name="score">
        <map>
            <entry key="英语" value="50"/>
            <entry key="语文" value="60"/>
        </map>
    </property>
</bean>        

<!-- 
config为properties文件的文件名,如果文件中的key为xxx.xxx,中间有点号时时必须用[‘xxx.xxx’]
如果key为xxx中间没有点时可以用config.xxx也可也用上面那种
 -->

 

使用注解简化配置文件

(1)组件扫描

1)什么是组件扫描?

容器会扫描base-package指定的包及其子包

下面所有的类,如果该类前面有一些特定的注解

(比如 @Component),则纳入容器进行管理(相当于

在配置文件当中有一个对应的bean元素一样)。

2)编程步骤

step1.在类前面添加一些特定的注解。

@Component  通用。

@Repository 持久层。

@Service   业务层。

@Controller  控制层。

step2.在配置文件当中,配置组件扫描。

 

 

(2)几个注解

 

(3)依赖注入相关的几个注解

1)@Autowired @Qualifier

a.支持set方法注入

 

b.支持构造器注入

2)@Resource(只支持set方法注入)(将该注解添加到set方法之前,或者也可以直接添加到属性前,name属性用来指定被注入bean的id)

 

3)@Value(放在set方法前会调用set方法,放在值前直接注入)   

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!