Spring入门

Spring简介

分层的,full-stack的轻量级开源框架

Spring两大核心

  • IoC控制反转 (反转的是对象的创建权) 最大的优点是解耦合
  • AOP面向切面编程 底层实现是动态代理 作用:程序方法在不修改的情况下进行增强

Spring的各个层的解决方案:

  • web层: SpringMVC
  • service层 :
  • DAO层:
    • spring JDBC Templae(类似DBUtils)
    • Spring Data JPA\Redis\Solr\ES等

Spring的优势

  1. 方便解耦 简化开发
  2. AOP编程的支持
  3. 声明式事务控制
    声明式:与之对应的是编程式 : XML和注解都称为声明
    1. 方便程序的测试
    2. 方便集成各种优秀框架
    3. 降低JavaEE的API的使用难度(封装)

Spring的发展

  • Spring Boot (轻代码 轻配置)
  • Spring Security 安全框架
  • Spring Cloud 用于分布式开发

Spring快速入门(IoC:让Spring框架创建Bean对象)

  1. 导入Spring相关jar包
    1. 导入核心容器的4个jar: beans, core, context, expression
    2. 框架会访问日志文件,导入日志相关API: apache-commons-logging.jar
    3. 开发中习惯让logging去继承log4j ,自动集成
    4. 5.
  2. 创建bean
  3. 创建xml
  4. 测试

配置文件的配置

配置文件放在src目录下,自己可以起名字,但是一般都是使用applicationContext.xml

0.导入约束

约束的位置在压缩包

spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html/xsd-configuration.html

约束为

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns=http://www.springframework.org/schema/beansxsi:schemaLocation="http://www.springframework.org/schema/beans ② http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ③">

① Xmlns(XML NameSpace) 声明命名空间,建议是用网址做命名空间,但并不会去访问改网址, 仅仅是 namespace 和 xsd(xsd 是 spring 这个 xml 的 schema 文件,里面定义配置内容)里 声明的 targetNamespace 保持一致 . 注:这里命名空间是改不了的,其实是在代码中也写死了,可以打开 spring-beans3.2.0.M1-sources.jar 包的 org\springframework\beans\factory\xml\BeanDefinitionParserDelegate.java 查看对 http://www.springframework.org/schema/beans这个namespace的定义。
② schemaLoacation .用于绑定命名空间的 schema 文件,通常是用 URL 值对,中间用空格隔 开,前面 URL 是命名空间,后面 URL 为 schema 的文件地址
③ xsd 的存放地址,如果没有声明,eclipse 会去网上下载.

1.基本配置

使用bean标签进行配置,和以前三层架构解耦合用的BeanFactory差不多,只有”暱称”和路径
- id:bean的实例,在spring容器中一个唯一的标识
- class:bean的全限定名

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>

2.Bean标签中scope的配置

scope的选择:
- singleton(默认值):单例
- prototype:原形 多例
需要注意的是,单例模式下,配置文件被加载,spring容器创建的时候,Bean对象就被创建了;而在多例模式下,在调用getBean的方法的时候,Bean对象才被创建

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" scope="prototype"></bean>

3.Bean生命周期相关的方法配置

也是Bean标签中的属性
- init-method:指定Bean初始化的时候,执行的方法
- destroy-mothod:指定Bean销毁时执行的方法

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>

通过这两个属性的设置,Bean中任何一个方法,都可以充当初始化方法,或销毁方法

单例对象生命周期归容器管理
多例归JVM垃圾回收机制管理

4.Bean实例化的三种方式

1.通过Bean无参构造创建对象(以上例子都是通过该方式创建的,也是最常用的方法)

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>

2.通过静态工厂的方式创建对象
如果一个Bean可以通过一个工厂的某个方法获得,name我们可以使用静态工厂的方式获取它
它有三个属性 id–>和以前一样,用来标识这个Bean; class–>这个class是工厂的位置,因为这个模式是通过工厂获取的Bean; method–>标识出具体哪一个方法用来生成我们想要的Bean

<bean id="userDao" class="com.cuixiaoming.factory.StaticBeanFactory" factory-method="getUserDao"></bean>

3.通过实例工厂的方式创建对象
这个和上一个的区别是,这种方法中,工厂Bean已经被配置到了spring容器中,所以我们不需要用class标识出工厂的位置,我们是用另一个属性factory-bean,标上工厂的id即可

<bean id="beanFactory" class="com.cuixiaoming.factory.InstanceBeanFactory"></bean>
<bean id="userDao" factory-bean="beanFactory" factory-method="getUserDao"></bean>

经过测试我发现,这两个工厂的方式的时候,当spring容器加载的时候,factory-method标注的方法都会执行一次,然后等到每次创建对象的时候,又会执行;

5.依赖注入(DI)的设置

注入之前,要在被注入的Bean中将注入的东西设为私有变量,并且提供set方法

property标签(位于Bean标签内)
- name: 是该实体的set方法的属性名称
- ref: 代表引用的id 引用容器中的那一个bean
- value: 注入普通字符串
- list: 注入list集合
- map: 注入map集合
- props: 注入props集合

1.注入Bean

我们用最基本的形式,要想执行dao层方法,需要先获得service对象,然后service对象再获得dao层对象,从而执行dao层方法,也就是说,需要在spring容器中获取两次;
如果,我们通过注入,将dao层对象注入到service对象中,我们在获得service对象的时候,就能一起获取到dao层对象,如下图所示;
注入

<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl"></bean>

<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao" ></property>
</bean>

2.注入普通字符串

将一个字符串设为私有变量,并提供名为setStr()的set方法,这样我们创建对象的时候,它里面已经包含这个字符串变量了;

<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
    <property name="str" value="这是一个value"></property>
</bean>

3.注入集合

注入集合是非常重要的知识点
一般来说,也是先设置成私有变量并提供set方法;然后在property中写个name,然后在标签内部写集合标签

 <bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
        <!-- list集合的注入 -->
        <property name="strList" >
            <list>
                <value>第一个</value>
                <value>第二个</value>
                <value>第三个</value>
            </list>
        </property>
    <!-- map集合的注入,里面两个user放在最下面了 -->
      <property name="userMap">
            <map>
                <entry key="user1" value-ref="user1"></entry>
                <entry key="user1" value-ref="user2"></entry>
            </map>
        </property>
    <!-- property集合的注入-->
        <property name="prop">
            <props>
                <prop key="p1">123</prop>
                <prop key="p2">456</prop>
                <prop key="p3">789</prop>
            </props>
        </property>
    </bean>

    <!-- map集合里面的两个user -->
    <bean id="user1" class="com.cuixiaoming.domain.User">
        <property name="username" value="张三"></property>
        <property name="age" value="23"></property>
    </bean><bean id="user2" class="com.cuixiaoming.domain.User">
        <property name="username" value="李四"></property>
        <property name="age" value="24"></property>
    </bean>

6.属性注入的三种方式

1.set注入

上面这些方式都是采用的set注入,就是在被注入的Bean里面,将注入的东西提取私有,提供set方法,不再赘述

2.有参构造注入

通过被注入的Bean提供有参和无参构造,(这种注入不使用无参构造,但是没有无参构造会导致其他功能不能使用,一般来说,只要给出有参构造,就要同时给出无参构造)

public UserDaoImpl() {
    System.out.println("dao层无参构造执行了");
}

public UserDaoImpl(String username,User user) {
    System.out.println("dao层有参构造执行了");
    System.out.println("username="+username);
    System.out.println("user=" +user);
}

配置文件
在Bean标签里面使用constructor-arg标签,这个标签可以使用键值,也可以继续注入其他Bean

<bean id="user1" class="com.cuixiaoming.domain.User">
    <property name="username" value="张三"></property>
    <property name="age" value="23"></property>
</bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl">
    <constructor-arg name="username" value="奥特曼"></constructor-arg>
    <constructor-arg name="user" ref="user1"></constructor-arg>
</bean>

<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>

需要注意的是,你的bean中constructor-arg的数据要至少和一个构造方法所有参数吻合,不然会报错

3.p命名空间注入

这个方法也是使用set方法进行的注入,不过,语法非常简单
首先,在约束上面加上这一句,就是把第一个约束复制改一下

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       <!--加上下面这一句,通过第一句修改而来-->
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

可以看出,它可以替代所有的set注入,而且语句极其简单

<bean id="user1" class="com.cuixiaoming.domain.User" p:username="张三" p:age="23"></bean>
<bean id="userDao" class="com.cuixiaoming.dao.impl.UserDaoImpl" p:str="这是一个字符串" p:user-ref="user1"></bean>
<bean id="userService" class="com.cuixiaoming.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>

7.导入其他的配置文件

这个是用于分布式开发,把多个配置文件合成一个
使用下面这个标签即可

<import resource=""/> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章