spring学习第一天

Spring框架的概述

什么是Spring

Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架

SUN提供的EE的三层结构:web层、业务层、数据访问层(持久层,集成层)

Struts2是web层基于MVC设计模式框架. Hibernate是持久的一个ORM的框架. Spring框架有对三层的一站式解决方案:

web层:Spring MVC 持久层:JDBC Template 业务层:Spring的Bean管理 Spring的出现是为了取代EJB的臃肿、低效、脱离现实

Spring的核心 IOC:(Inverse of Control 反转控制)

控制反转:将对象的创建权,交由Spring完成. AOP : Aspect Oriented Programming 是 面向对象的功能延伸.不是替换面向对象,是用来解决OO中一些问题.

Spring的版本

Spring3.x和Spring4.x Spring4需要整合hibernate4. Spring优点 方便解耦,简化开发 Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理

AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能 声明式事务的支持 只需要通过配置就可以完成对事务的管理,而无需手动编程 方便程序的测试 Spring对Junit4支持,可以通过注解方便的测试Spring程序 方便集成各种优秀框架 Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持 降低JavaEE API的使用难度 Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

Spring体系结构

Spring 框架是一个分层架构,它包含一系列的功能要素并被分为大约20个模块。这些模块分为Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和测试部分,如下图所示:

Spring的快速入门

1. 下载Spring的开发包

官方下载Spring 3.x 最新开发版本

http://www.springsource.org/download/community Spring开发包 : spring-framework-3.2.0.RELEASE-dist.zip

docs : spring框架api和规范 libs : spring开发的jar包 schema : XML的约束文档. Spring开发中的依赖包 : spring-framework-3.0.2.RELEASE-dependencies.zip

2. 创建web工程引入相应jar包

spring-beans-3.2.0.RELEASE.jar spring-context-3.2.0.RELEASE.jar spring-core-3.2.0.RELEASE.jar spring-expression-3.2.0.RELEASE.jar

开发的日志记录的包:

com.springsource.org.apache.commons.logging-1.1.1.jar : 用于整合其他的日志的包(类似Hibernate中slf4j) com.springsource.org.apache.log4j-1.2.15.jar

3. 创建Spring的配置文件

在src下创建一个applicationContext.xml 引入XML的约束 找到xsd-config.html.引入beans约束

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- bean definitions here -->

    </beans>

4. 在配置中配置类

<!-- 通过一个<bean>标签设置类的信息,通过id属性为类起个标识. -->
<bean id="userService" class="cn.itcast.spring3.demo1.HelloServiceImpl"></bean>

5. 创建测试类

ApplicationContext 应用上下文,加载Spring 框架配置文件

加载classpath:

new ClassPathXmlApplicationContext(“applicationContext.xml”);

加载磁盘路径:

new FileSystemXmlApplicationContext(“applicationContext.xml”);

@Test

// Spring开发

public void demo2() {

    // 创建一个工厂类.

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(  "applicationContext.xml");

    HelloService helloService = (HelloService) applicationContext.getBean("userService");

    helloService.sayHello();

}

类创建的传统方式 HelloTest类中使用 HelloService类对象

传统方式: HelloService helloService = new HelloService();

IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建HelloService对象的控制权,交由Spring框架管理,简单说,就是创建HelloService对象控制权被反转到了Spring框架

IOC和DI区别 IOC:控制反转:将对象的创建权,由Spring管理. DI:依赖注入:在Spring创建对象的过程中,把对象依赖的属性注入到类中.

面向对象中对象之间的关系;

依赖:

public class A{
private B b;
}

* 继承:is a
* 聚合:
    * 聚集:
    * 组合:

BeanFactory与ApplicationContext区别

ApplicationContext类继承了BeanFactory

BeanFactory在使用到这个类的getBean()方法的时候,才会加载这个类.

ApplicationContext类加载配置文件的时候,创建所有的类

ApplicationContext对BeanFactory提供了扩展:

  • 国际化处理
  • 事件传递
  • Bean自动装配
  • 各种不同应用层的Context实现
  • 早期开发使用BeanFactory.

    @Test
    
    public void demo4(){
    
        // ClassPathResource  FileSystemResource
    
        BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("applicationContext.xml"))</u>;
    
        HelloService helloService = (HelloService) beanFactory.getBean("userService");
    
        helloService.sayHello();
    
    }
    

MyEclipse配置XML提示

Spring框架Bean实例化的方式

  • 三种方式实例化Bean
    • 构造方法实例化(默认无参数)
    • 静态工厂实例化
    • 实例工厂实例化

无参数构造方法的实例化

<!-- 默认情况下使用的就是无参数的构造方法. -->
<bean id="bean1" class="cn.itcast.spring3.demo2.Bean1"></bean>

静态工厂实例化 – 简单工厂模式

<!-- 第二种使用静态工厂实例化 -->

<bean id="bean2" class="cn.itcast.spring3.demo2.Bean2Factory" factory-method="getBean2"></bean>

实例工厂实例化 – 工厂方法模式

<!-- 第三种使用实例工厂实例化 -->

<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>

<bean id="bean3Factory" class="cn.itcast.spring3.demo2.Bean3Factory"/>

public class PersonServiceFactory {
    public  PersonService  createPersonService(){
        return new PersonServiceImpl();
       }
}
/**
 * Bean的实例化的测试
 * 
 * @author 姜涛
 * 
 */
public class SpringTest2 {
    @Test
    // 无参数的构造方法的实例化
    public void demo1() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
        System.out.println(bean1);
    }

    @Test
    // 静态工厂实例化
    public void demo2() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
        System.out.println(bean2);
    }
    @Test
    // 实例工厂实例化
    public void demo3() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
        System.out.println(bean3);
    }

Bean的其他配置

Bean的命名 id属性和name属性

  • 一般情况下,装配一个Bean时,通过指定一个id属性作为Bean的名称
  • id 属性在IoC容器中必须是唯一的
  • id 的命名要满足XML对ID属性命名规范
    • id遵守XML约束的id的约束.id约束保证这个属性的值是唯一的,而且必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号
  • 如果Bean的名称中含有特殊字符,就需要使用name属性
  • 例如:
  • 因为name属性可以相同,所以后出现Bean会覆盖之前出现的同名的Bean

类的作用范围 ##

  • scope属性 :
    • singleton : 单例的(默认的值)
    • prototype : 多例的
    • request : web开发中创建了一个对象,将这个对象存入request范围,request.setAttribute();
    • session : web开发中.创建了一个对象,将这个对象存入session范围,session.setAttribute();
    • globalSession :一般用于Porlet应用环境.指的是分布式开发.不是porlet环境,globalSession等同于session;
  • 实际开发中主要使用 singleton,prototype

Bean的生命周期

  • 配置Bean的初始化和销毁的方法:在xml文件中加入:

    • init-method=”setup”
    • destroy-method=”teardown”
  • 执行销毁的时候,必须手动关闭工厂,而且只对scope=singleton有效

    • 必须用子类执行 ClassPathXmlApplicationContext 中的close方法来实现。

Bean的生命周期的11个步骤

  • 1 . bean对象实例化 : instantiate bean
  • 2 . 属性的注入: populate properties : 封装属性
  • 3 . 注入配置的类的名称 : 如果Bean实现BeanNameAware 执行 setBeanName
  • 4 . 注入applicationContext : 如果Bean实现BeanFactoryAware 或者 k 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
  • 5 . 初始化之前执行操作 : 如果存在类实现 BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization 需要添加此标签:
  • 6 . 属性设置后执行操作 : 如果Bean实现InitializingBean 执行 afterPropertiesSet
  • 7 . 调用手动设置的初始化方法 : 调用 指定初始化方法 init
  • 8 . 初始化后执行操作 : 如果存在类实现 BeanPostProcessor(处理Bean),执行 postProcessAfterInitialization
  • 9 . 执行业务处理
  • 10 . 调用销毁的方法 : 如果Bean实现 DisposableBean 执行 destroy
  • 11 . 调用手动销毁方法 : 调用 指定销毁方法 customerDestroy
  • 案例:在CustomerService类的add方法之前进行权限校验
  • xml配置
  • <bean class="cn.itcast.spring3.demo4.MyBeanPostProcessor"></bean>
    //这里不需要写id,因为这是由Spring容器自动调用的。
    

CustomerService & CustomerServiceImpl

public interface CustomerService {
    public void add();
    public void find();
}



public class CustomerServiceImpl implements CustomerService, BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean   {
    private String name;

    public void setName(String name) {
        System.out.println("第二步:属性的注入.");
        this.name = name;
    }

    public CustomerServiceImpl() {
        super();
        System.out.println("第一步:实例化类.");
    }

    public void add(){
        System.out.println("添加客户...");
    }

    public void find(){
        System.out.println("查询客户...");
    }

    public void setBeanName(String name) {
        System.out.println("第三步:注入配置的类的名称"+name);
    }

    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        System.out.println("第四步:注入applicationContext"+applicationContext);
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:属性设置后执行...");
    }

    public void setup(){
        System.out.println("第七步:调用手动设置的初始化方法...");
    }

    public void destroy() throws Exception {
        System.out.println("第十步:调用销毁的方法...");
    }

    public void teardown(){
        System.out.println("第十一步:调用手动销毁方法...");
    }
}

MyBeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor{
    /**
     * bean:实例对象
     * beanName:在配置文件中配置的类的标识.
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("第五步:初始化之前执行...");
        return bean;
    }

    public Object postProcessAfterInitialization(final Object bean, String beanName)
            throws BeansException {
        System.out.println("第八步:初始化后执行...");
        // 动态代理:
        if(beanName.equals("customerService")){
            Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces() , new InvocationHandler() {
                // 调用目标方法的时候,调用invoke方法.
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    if("add".equals(method.getName())){
                        System.out.println("权限校验...");
                        Object result = method.invoke(bean, args);
                        //System.out.println(System.currentTimeMillis());
                        return result;
                    }
                    return method.invoke(bean, args);
                }
            });
            return proxy;
        }
        return bean;
    }

}

Spring Test

public class SpringTest4 {

    @Test
    // Bean完整的生命周期
    public void demo1() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");

        CustomerService customerService = (CustomerService) applicationContext.getBean("customerService");
        customerService.add();
        customerService.find();

        applicationContext.close();
    }
}


//结果如下:
第一步:实例化类
第二步:属性的注入
第三步:注入配置的类的名称 customerService
第四步:注入applicationContext org.springframework.context.support.ClassPathXmlApplicationContext@61baa894: startup date [Wed Jun 22 11:49:14 CST 2016]; root of context hierarchy
第五步:初始化之前执行...
第六步:属性设置后执行...
第七步:调用手动设置的初始化方法...
第八步:初始化后执行...
权限校验...
添加客户...
查询客户...
11:49:14,863  INFO ClassPathXmlApplicationContext:1042 - Closing org.springframework.context.support.ClassPathXmlApplicationContext@61baa894: startup date [Wed Jun 22 11:49:14 CST 2016]; root of context hierarchy
11:49:14,864  INFO DefaultListableBeanFactory:444 - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@64bfbc86: defining beans [customerService,test.spring3.demo4.MyBeanPostProcessor#0]; root of factory hierarchy
第十步:调用销毁的方法...
第十一步:调用手动销毁的方法...