Spring框架之入门(1)

Spring 框架概述 
1.1. 什么是Spring 
Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架 
分层: 来自JavaEE体系结构 (客户端层、 web层、业务层、持久层 ) 
服务器端三层结构 (web层、业务层、持久层) 
Servlet + JSP —- web层技术 —- Struts2框架 
JDBC 接口 —- 持久化技术 —- Hibernate框架 
EJB 框架(复杂) —- 业务层技术 —- Spring 框架 (取代EJB出现 )

Spring 出现,就是为了解决常见JavaEE 企业开发问题 ! 
一站式: Spring框架提供了 web层(表现层) SpringMVC、 业务层 IoC、AOP和事务管理、 持久层JdbcTemplate 各层javaEE软件开发解决方案 
轻量级:相对于EJB框架而言

Spring核心 
IoC: 控制反转 
AOP: 面向切面编程 
官网:http://www.springsource.org/

Spring 给软件开发带来了什么 
方便解耦,简化开发 (Spring IoC特性) 
AOP编程的支持 
声明式事务的支持 
方便程序的测试 
方便集成各种优秀框架 (整合Struts2 、 Hibernate 、MyBatis 、Struts1 ) 
降低JavaEE API的使用难度 (Spring 提供大量工具类, 简化代码编写 )

Spring 体系结构

体系结构

Spring框架IoC和DI

下载开发包 
http://projects.spring.io/spring-framework/ 网址下载开发包 
最新版本4.1 课程 3.2

开发包3.2 
spring-framework-3.2.0.RELEASE-dist.zip 
依赖吧 3.0 (常见开源技术jar包) 
spring-framework-3.0.2.RELEASE-dependencies.zip

Spring目录结构

 

导入jar包到项目 
进行Ioc和DI的开发,只需要导入最核心spring的jar包 
spring核心jar包

Spring运行,使用commons-logging日志技术 
(commons-logging 和 slf4j 都属于统一日志接口, 整合log4j日志实现 ) 
导入log4j jar

理解IoC和DI的概念 
什么是IoC ? 什么是DI ? 区别是什么? 
IoC: 控制反转, 解决程序对象紧密耦合问题(工厂+反射+ 配置文件), 将程序中原来构造对象的权限,交给IoC容器来构造,当程序需要对象,找IoC容器获取。

IOC

DI : 依赖注入 , IoC容器需要为程序提供依赖对象,返回对象所依赖对象一同可以提供(Servlet需要Service, 找Ioc容器获取Service, Service由容器提供,Service依赖DAO ,IoC容器提供Service对象同时, 将Service依赖DAO 注入到Service中)

编写IoC和DI入门案例 
IOC&DI

tra

将所有对象,交给IoC容器(Spring)来管理

(spring配置文件 通常可以在src 或者 WEB-INF目录下, 通常名称 applicationContext.xml ) 
参考文档 : xsd-config.html 
通过applicationContext.xml 配置Spring管理对象

在程序中通过ApplicationContext接口 获取spring工厂对象 
1.ClassPathXmlApplicationContext 读取 src下配置文件 
2.FileSystemXmlApplicationContext 读取WEB-INF下配置文件 
IoC 通过工厂,从Spring容器获取创建好对象

@Test
    public void testRegist2() {
        // 从Ioc容器获得对象
        // 1、 获取Ioc容器工厂对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 2、 从Ioc容器工厂 获取需要对象 (根据bean的id 获取)
        UserServlet userServlet = (UserServlet) applicationContext.getBean("userServlet");
        userServlet.regist();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

DI 在通过工厂获取,spring对象时,spring同时提供对象所依赖的对象

// 依赖注入 (Spring 在构造 UserServlet对象时,同时将构造好 UserService对象,注入到UserServlet对象中 )
    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

配置

<!-- 将对象的创建权,交给容器管理 -->
    <bean id="userServlet" class="cn.itcast.spring.a_quickstart.UserServlet" >
        <!-- 返回UserServlet时,同时提供 依赖的UserService对象 -->
        <!-- 
            name 属性 对应 对象中 setXXX 方法, 代表对象中含有某个属性
            ref 引用了另一个Bean对象id 
         -->
        <property name="userService" ref="userService" />
    </bean>
    <bean id="userService" class="cn.itcast.spring.a_quickstart.UserServiceImpl"/>
    <bean id="userDAO" class="cn.itcast.spring.a_quickstart.UserDAOImpl" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

BeanFactory 和 ApplicationContext 接口 
ApplicationContext 是 BeanFactory 子接口,BeanFactory 才是Spring框架最核心工厂接口。 
ApplicationContext 是对BeanFactory 接口扩展, 企业开发很少直接使用BeanFactory 
ApplicationContext 会在容器初始化时,对其中管理Bean对象进行创建, BeanFactory 会在对象获取时才进行初始化 。

IoC容器装配Bean(xml配置) 
3.1.三种实例化Bean的方式 
方式一: 使用类构造器实例化对象

<!-- 方式一  使用构造器(无参数)实例化对象  -->
    <bean id="bean1" 
class="cn.itcast.spring.b_instance.Bean1" />
  • 1
  • 2
  • 3
  • 4

方式二: 使用静态工厂 静态方法,对对象实例化

<!-- 方式二 使用静态工厂实例化对象 -->
    <!-- 调用 工厂的 factory-method 返回对象 -->
    <bean id="bean2" 
class="cn.itcast.spring.b_instance.Bean2Factory" factory-method="getBean2" />
  • 1
  • 2
  • 3
  • 4
  • 5

方式三: 使用实例工厂 实例方法 对对象实例化


<!-- 方式三 使用实例工厂实例化对象 -->
    <!-- 先实例化工厂 -->
    <bean id="bean3Factory" class="cn.itcast.spring.b_instance.Bean3Factory" />
    <!-- 再通过工厂对象的实例方法,构造目标对象 -->
    <bean id="bean3" factory-bean="bean3Factory" 
factory-method="getBean3" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

应用场景: 大多数情况,可以通过构造器直接实例化, 只有在对象构造过程非常复杂的情况下,才会采用工厂实例化的方式

Bean的作用域 
最常用 singleton 和 prototype 两种 
Singleton (单例): 在一个BeanFactory对象中,引用唯一的一个目标实例 
Prototype (多例): 每次通过工厂执行getBean时,返回不同实例对象 
Request (请求范围) : 创建对象保存在request范围,如果request销毁,对象销毁 
Session (会话范围): 创建对象保存Session中, 如果session销毁,对象销毁 
* globalSession (全局会话 ) :分布式系统,全局会话的概念, 一次登录,应用多个系统

<!-- 第三部分 Bean的作用域 -->
    <!-- 通过scope属性,指定bean作用域 (默认作用域 singleton) -->
    <bean id="singletonBean" class="cn.itcast.spring.c_scope.SingletonBean" /><!-- 单例 -->
    <bean id="prototypeBean" class="cn.itcast.spring.c_scope.PrototypeBean" scope="prototype"/> <!-- 多例 -->
  • 1
  • 2
  • 3
  • 4

单例Bean 在容器初始化时,实例化 (只实例化一次 ) 
多例Bean 在工程执行getBean时 才会实例化 (每调用一次,返回不同对象 )

Bean的生命周期 
可以通过 init-method属性配置 Bean对象初始化执行方法,destory-method属性配置Bean对象销毁的方法 
(初始化方法和构造方法 有区别? 构造方法作用申请空间,为对象基本属性初始化 , 初始化方法 对象复杂构造过程 , java语言建议将对象复杂构造过程单独抽取 初始化方法 )

public class LifeCycleBean implements IHello {
    public LifeCycleBean() {
        System.out.println("LifeCycleBean 构造...");
    }

    public void setup() {
        System.out.println("LifeCycleBean 初始化...");
    }

    public void teardown() {
        System.out.println("LifeCycleBean 销毁...");
    }

    @Override
    public void sayHello() {
        System.out.println("hello ,itcast...");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

配置

<!-- 第四部分  bean的生命周期 -->
    <bean id="lifeCycleBean" class="cn.itcast.spring.d_lifecycle.LifeCycleBean" 
        init-method="setup" destroy-method="teardown" />
  • 1
  • 2
  • 3

在对象构造后,立即执行初始化init , 默认没有执行destroy 销毁方法

public class LifeCycleTest {
    @Test
    public void testInitDestroy() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        IHello lifeCycleBean = (IHello) applicationContext.getBean("lifeCycleBean");
        System.out.println(lifeCycleBean);
        lifeCycleBean.sayHello();

        // 必须手动调用 容器销毁的方法 --- web服务器tomcat,自动调用容器销毁
        applicationContext.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

后处理器(后处理Bean)— 补充

在Spring构造Bean对象过程中,有一个环节对Bean对象进行 后处理操作 (钩子函数) —– Spring 提供 BeanPostProcessor 接口 
可以自定义类,实现 BeanPostProcessor 接口,配置到Spring容器中,在构造对象时,spring容器会调用接口中方法

后处理器,在对象构造过程中,提供代理, 是AOP自动代理核心 !

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    /**
     * bean 代表Spring容器创建对象
     * beanName 代表配置对象对应 id属性
     */
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            System.out.println("后处理器 初始化后执行...");
        }
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        // 针对bean id 为 lifeCycleBean的对象 进行代理
        if (beanName.equals("lifeCycleBean")) {
            System.out.println("后处理器 初始化前执行...");
            return Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("执行代理.....");
                    return method.invoke(bean, args);
                }
            });
        }
        return bean;
    }
}
  •  

Bean的依赖注入

三种注入方式

构造参数的属性输入

public class Car {
    private String name;
    private double price;

    // 为Car类 提供构造方法
    public Car(String name, double price) {
        super();
        this.name = name;
        this.price = price;
    }

通过constructor-arg 属性进行构造参数注入

<!-- 构造方法属性注入 -->
    <bean id="car" class="cn.itcast.spring.e_di.Car">
        <!-- 通过constructor-arg 注入构造函数的参数 -->
        <!-- index 代表参数顺序 ,第一个参数 0
             type 代表参数类型 
             name 代表参数的名称 
             value 注入参数的值
             ref  引用另一个bean元素的id
         -->
        <constructor-arg index="0" type="java.lang.String" value="宝马"/>
        <constructor-arg index="1" type="double" value="1000000"/>
    </bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

setter方法属性注入

public class Employee {
    private int id;
    private String name;

    private Car car;// 复杂元素

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setCar(Car car) {
        this.car = car;
    }

在配置文件 使用 元素完成setter属性注入

<!-- setter方法属性注入 -->
    <bean id="employee" class="cn.itcast.spring.e_di.Employee" >
        <!-- 通过property 注入setter方法属性 (属性名称, 由setter方法推理获得)-->
        <!-- 
            name 属性名称 (由setter方法获得)
            value 注入参数的值
            ref 引用另一个Bean元素的id
         -->
        <property name="id" value="100001" />
        <property name="name" value="张三" />
        <!-- 注入复杂对象 -->
        <property name="car" ref="car" />
    </bean>

属性注入深入 
【知识点】 p名称空间的使用 
P名称空间,在spring2.5版本后引入,为了简化属性依赖注入(setter方法) 
第一步: 在配置文件,引入p名称空间

xmlns:p="http://www.springframework.org/schema/p"
  • 1

第二步: 简化setter方法注入配置

<!-- 使用p命名空间注入 -->
    <bean id="employee2" class="cn.itcast.spring.e_di.Employee" 
        p:eid="100002" p:name="李四" p:car-ref="car"/>

【知识点】 spEL表达式的使用 
在spring3.0之后,引入spEL 表达式语言,简化属性注入 
参考 “Spring_表达式语言.pdf” 学习 
语法: #{表达式} 
用法一: 直接通过value注入,引用一个Bean对象 
用法二: 引用一个Bean对象属性 
用法三: 直接调用对象的方法

  •  
<!-- spEL使用 -->
    <bean id="valueBean" class="cn.itcast.spring.e_di.ValueBean" />
    <bean id="employee3" class="cn.itcast.spring.e_di.Employee" >
        <!-- 调用valueBean的getId -->
        <property name="eid" value="#{valueBean.id}" />
        <!-- 直接调用对象的方法 -->
        <property name="name" value="#{valueBean.pickName().toUpperCase()}" />
        <!-- #{car} 效果类似 ref  -->
        <property name="car" value="#{car}" />
    </bean>

集合元素类型属性注入

Spring为每种集合都提供一个元素标签 进行注入

public class CollectionBean {
    private List<String> list;
    private Set<Integer> set;
    private Map<String, Integer> map;
    private Properties properties;

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<Integer> set) {
        this.set = set;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
<!-- 集合类型属性注入 -->
    <bean id="collectionBean" class="cn.itcast.spring.e_di.CollectionBean">
        <!-- 
            array 注入数组
            list 注入List集合
            set 注入Set集合
            map 注入Map集合
            props 注入 Properties 集合
         -->
        <property name="list">
            <list>
                <!-- 
                    value 注入基本数据类型, String 类型
                    ref 注入引用Bean的id
                 -->
                 <value>aaa</value>
                 <value>bbb</value>
                 <value>ccc</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>10</value>
                <value>10</value>
                <value>20</value>
            </set>
        </property>
        <property name="map">
            <map>
                <!-- map中每个元素都是键值对 -->
                <entry key="abc" value="10"></entry>
                <entry key="def" value="20"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="qwe123">asd456</prop>
                <prop key="tyu567">hjk789</prop>
            </props>
        </property>
    </bean>
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资源 5来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资 5源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值