1.1 Spring框架的概述

1.1.1什么是Spring

  • Spring是分层的JavaSE和JavaEES一站式轻量级开源框架。

    • 分层:

      • SUN提供的EE的三层结构:web层、业务层、数据访问层(持久层、集成层)。
      • Struts2是web层基于MVC设计模式框架。
      • Hibernate是持久层的一个ORM框架。
    • 一站式:
      • Spring框架有对三层的每层解决方案:
      • web层:Spring MVC。
      • 持久层:JDBC Template。
      • 业务层:Spring的Bean管理。

1.1.2Spring的核心

  • IOC(Inverse of control):控制反转。

    • 控制反转:将对象的创建权,交由Spring管理。
    • IOC原理:

  • AOP(Aspect Oriented Programming):面向切面编程。

    • 面向切面编程:是面向对象的功能延伸,不是替换面向对象,是用来解决面向对象的一些问题。 

1.1.3Spring的版本

  • Spring3.x版本和Spring4.x版本。Spring4.x版本需要整合Hibernate4.x版本。

1.1.4EJB:企业级的JavaBean

  • EJB:SUN公司提出的EE解决方案。

1.1.5Spring的优点

  • 方便解耦,简化开发

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

1.2 Spring的入门        

1.2.1Spring的体系结构

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

1.2.2下载Spring的开发包

  • spring-framework-3.2.0.RELEASE-dist.zip     --Spring开发包

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

1.2.3创建web工程并引入相应的jar包。

  • Core Container:

    • spring-beans-3.2.0.RELEASE.jar
    • spring-core-3.2.0.RELEASE.jar
    • spring-context-3.2.0.RELEASE.jar
    • spring-expression-3.2.0.RELEASE.jar
  • 开发的日志记录的jar包:
    • com.springsource.org.apache.commons.logging-1.1.1.jar  用于整合其他的日志的jar包(类似于Hibernate中的slf4j)
    • com.springsource.org.apache.log4j-1.2.15.jar  

1.2.4创建Spring的配置文件

  • 在src下新建一个applicationContext.xml文件
  • 引入XML的约束:
<?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"> 

 </beans>

1.2.5引入log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

 1.2.6体验传统开发和Spring开发

  • 创建一个接口:HelloService.java。
package cn.spring3.demo1;
/**
 * 入门的案例
 */
public interface HelloService {
    public void sayHello();
}
  • 创建一个实现类:HelloServiceImpl.java。
package cn.spring3.demo1;

public class HelloServiceImpl implements HelloService {

    @Override
    public void sayHello() {
        System.out.println("Hello Spring");

    }

}
  • 传统方式开发--多态
  @Test
    //传统方式
    public void demo1(){
        HelloService helloService = new HelloServiceImpl();
        helloService.sayHello();
    }
  • Spring开发

    • 要在applicationContext.xml文件中配置<bean>标签

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

    • applicationContext.xml文件中内容如下:
<?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>标签设置类的信息,通过id属性为类起个标识
      -->
     <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
 </beans>      
    • 测试代码
  @Test
    //Spring开发
    public void demo2(){
        //创建一个工厂类
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl");
        helloService.sayHello();
    }

1.2.7IOC和DI的区别?

  • IOC:控制反转,将对象的创建权,交由Spring管理。
  • DI:依赖注入,在Spring创建对象的过程之中,把对象的属性注入到类中。
    • 面向对象中对象之间的关系

      • 依赖:
public class A{
      private B b;
}
      • 继承:is a。
      • 聚合:
        • 聚集
        • 组合
    • 示例:
      • HelloService.java类
package cn.spring3.demo1;
/**
 * 入门的案例
 */
public interface HelloService {
    public void sayHello();
}
      • HelloServiceImpl.java类    
package cn.spring3.demo1;

public class HelloServiceImpl implements HelloService {
    private String info;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    @Override
    public void sayHello() {
        System.out.println("Hello"+info);

    }

}
      • applicationContext.xml
<?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>标签设置类的信息,通过id属性为类起个标识
      -->
     <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl">
         <!-- 使用 <property>标签注入属性-->
         <property name="info" value="Spring"></property>
     </bean>
 </beans>      
      • 测试代码
  @Test
    //Spring开发
    public void demo2(){
        //创建一个工厂类
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl");
        helloService.sayHello();

    }

1.2.8Spring框架加载配置文件

  • ApplicationContext(应用上下文),加载Spring框架配置文件。

    • 加载classpath:

      • new ClassPathXmlApplicationContext("applicationContext.xml");            :加载classpath下面配置文件。
    • 加载磁盘路径:
      • new FileSystemXmlApplicationContext("applicationContext.xml");       :加载磁盘下配置文件。

1.2.9BeanFactory和ApplicationContext区别?

  • ApplicationContext类继承了BeanFactory。
  • BeanFactory在使用到这个类的时候,getBean()方法才会加载到这个类。(延迟加载)。
  • ApplicationContext类加载配置文件的时候,创建所有的类。
  • ApplicationContext对BeanFactory提供了扩展的功能。
    • 国际化处理。
    • 事件传递。
    • Bean自动装配。
    • 各种不同应用层的Context实现。
  • ****早期开发使用BeanFactory。

1.2.10MyEclipse配置XML提示

  • 复制Schema的Location。

  • windows--preferences--XML Catalog

                  

1.3 IOC装配Bean    

1.3.1Spring框架Bean实例的方式:

  • 提供了三种方式实例化Bean。

    • 构造方法实例化:(默认无参数)--反射

      • <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
package cn.spring3.demo2;
/**
 * 使用无参数的方法实例化
 */
public class Bean1 {

}
<bean id="bean1" class="cn.spring3.demo2.Bean1"></bean>
  @Test
    //无参数的构造方法实例化
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean1 bean1= (Bean1) applicationContext.getBean("bean1");
        System.out.println(bean1);
    }
    • 静态工厂方法实例化(简单工厂模式)--反射+简单工厂
package cn.spring3.demo2;
/**
 * 使用静态工厂实例化
 */
public class Bean2 {

}
package cn.spring3.demo2;
/**
 * Bean2的静态工厂
 */
public class Bean2Factory {
    public static Bean2 getBean2Instance(){
        return new Bean2();
    }
}
<bean id="bean2Factory" class="cn.spring3.demo2.Bean2Factory" factory-method="getBean2Instance" ></bean>
  @Test
    //使用静态工厂实例化
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean2 bean2= (Bean2) applicationContext.getBean("bean2Factory");
        System.out.println(bean2);
    }
    • 实例工厂实例化(工厂方法模式) ---反射+实例工厂 
package cn.spring3.demo2;
/**
 * 使用实例工厂
 */
public class Bean3Factory {
    public Bean3 getBean3Instance(){
        return new Bean3();
    }
}
package cn.spring3.demo2;
/**
 * 使用实例工厂实例化
 */
public class Bean3 {

}
   <!-- 用来初始化Bean3Factory -->
     <bean id="bean3Factory" class="cn.spring3.demo2.Bean3Factory"></bean>
     <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3Instance" ></bean>
  @Test
    //使用实例工厂实例化
    public void demo3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Bean3 bean3= (Bean3) applicationContext.getBean("bean3");
        System.out.println(bean3);
    }
  • 分析:

    • 构造方法实例化:(默认无参数)--反射

      • 直接给Spring一个完整的类名,Spring就会帮助我们实例化对象。
    • 静态工厂方法实例化(简单工厂模式)
      • 要给一个factory-method,因为静态方法可以直接通过类名.方法()的形式来调用方法,而class="",当然是静态工厂的类名了,因为只有这样Spring才能帮助我们初始化工厂,返回需要的实例化对象。
    • 实例工厂实例化(工厂方法模式)
      • 之所以要实例化工厂,因为实例工厂不是静态工厂,不可以通过类名.方法()的形式调用方法,所以必须先让Spring来实例化实例工厂,然后再告诉Spring实例工厂的对象名是什么以及什么方法来实例化对象的。

1.3.2Bean的其他配置 

    • id和name的区别           

      • id遵守XML约束的id的约束。id约束保证这个属性的值是唯一的,而且必须以字母开始,可以使用字母、数字、连字符、下划线、句号、冒号。
      • name没有这些要求
        • 如果bean标签上没有配置id,那么name可以作为id。
      • 早期开发的时候,Spring整合Struts1,"/login"是特殊字符,只能使用name。
        • <bean name="/login"/>
      • 现在的开发中都使用id属性即可。  
  • 类的作用范围: 

    • scope属性:

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

    • 配置Bean的初始化的销毁的方法

      • init-method="setUp"。
      • destory-method="teardown" 。
    • 执行销毁的时候,必须手动关系工厂,而且支队scope="singleton"有效。 
    • 示例:

      • Product.java
package cn.spring3.demo3;

public class Product {

    //初始化的方法
    public void setup(){
        System.out.println("初始化的方法");
    }
    //销毁的方法
    public void teardown(){
        System.out.println("销毁的方法");
    }
}
      • applicationContext.xml
<bean id="product" class="cn.spring3.demo3.Product" init-method="setup" destroy-method="teardown"/>
      • 测试代码:
  @Test
    //测试初始化和销毁的方法
    public void demo1(){
        ClassPathXmlApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product = (Product) applicationContext.getBean("product");
        applicationContext.close();
    }
    • Bean的生命周期的11个步骤:
      1. instantiate bean对象示例化。
      2. populate properties 封装属性。
      3. 如果Bean实现BeanNameAware 执行setBeanName。
      4. 如果Bean实现BeanFactoryAware或者ApplicationContextAware设置工厂setBeanFactory或者上下文对象setApplicationContext。
      5. 如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization。
      6. 如果Bean实现initializingBean,执行afterPropertiesSet。
      7. 调用<bean init-method="init"> 指定初始化方法init。
      8. 如果存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization。
      9. 执行业务处理。
      10. 如果Bean实现DisposableBean,执行destory。
      11. 调用<bean destory-method="destory">,指定销毁方法destory。

1.3.3Bean中属性的注入 

  • Spring支持构造器注入和setter()方法注入。

    • 构造器注入
package cn.spring3.demo4;

public class Car {
    private String name;
    private Double price;
    public Car(){}
    public Car(String name, Double price) {
        super();
        this.name = name;
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car [name=" + name + ", price=" + price + "]";
    }

}
<!-- bean的属性注入 -->
     <bean id="car" class="cn.spring3.demo4.Car" >
         <constructor-arg index="0" value="宝马" />
         <constructor-arg index="1" value="300000.0"/>
     </bean>
  @Test
    public void demo1(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car =  (Car) applicationContext.getBean("car");
        System.out.println(car);;
    }
    • setter()方法注入

      • 普通属性  
package cn.spring3.demo4;

public class Car2 {
    private String name;
    private Double price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car2 [name=" + name + ", price=" + price + "]";
    }

}
<bean id="car2" class="cn.spring3.demo4.Car2">
         <property name="name" value="宝马"/>
         <property name="price" value="300000.0"/>
     </bean>
  @Test
    public void demo2(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Car2 car2 =  (Car2) applicationContext.getBean("car2");
        System.out.println(car2);;
    }
      • 对象属性
package cn.spring3.demo4;

public class Car2 {
    private String name;
    private Double price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car2 [name=" + name + ", price=" + price + "]";
    }

}
package cn.spring3.demo4;

public class Person {
    private String name;
    private Car2 car;

    public String getName() {
        return name;
    }

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

    public Car2 getCar() {
        return car;
    }

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

    @Override
    public String toString() {
        return "Person [name=" + name + ", car=" + car + "]";
    }

}
<bean id="car2" class="cn.spring3.demo4.Car2">
         <property name="name" value="宝马"/>
         <property name="price" value="300000.0"/>
     </bean>

     <bean id="person" class="cn.spring3.demo4.Person">
         <property name="name" value="神经病"/>
         <property name="car" ref="car2"/>
     </bean>
  @Test
    public void demo3(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person =  (Person) applicationContext.getBean("person");
        System.out.println(person);;
    }
    • 命名空间p注入属性

      • 为了简化XML的文件配置,Spring从2.5开始引入了一个新的p名称空间。
      • p:属性名="xxx" 引入常量值。
      • p:属性名-ref="xxx" 引入其他bean对象
package cn.spring3.demo4;

public class Car2 {
    private String name;
    private Double price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car2 [name=" + name + ", price=" + price + "]";
    }

}
package cn.spring3.demo4;

public class Person {
    private String name;
    private Car2 car;

    public String getName() {
        return name;
    }

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

    public Car2 getCar() {
        return car;
    }

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

    @Override
    public String toString() {
        return "Person [name=" + name + ", car=" + car + "]";
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<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"> 

     <bean id="car2" class="cn.spring3.demo4.Car2" p:name="宝马" p:price="200000.0"/>

     <bean id="person" class="cn.spring3.demo4.Person" p:name="神精病" p:car-ref="car2"/>
 </beans>
  @Test
    public void demo3(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person =  (Person) applicationContext.getBean("person");
        System.out.println(person);;
    }
    • SPEL: Spring Expression Language,Spring表达式语言,对依赖注入进行简化。

      • 语法:#{表示式}
      • <bean id="" value="#{}"/>
package cn.spring3.demo5;

public class Product {
    private String name;

    public String getName() {
        return name;
    }

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

}
<?xml version="1.0" encoding="UTF-8"?>
<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"> 

     <bean id="product" class="cn.spring3.demo5.Product" >
         <property name="name" value="#{'哇哈哈'}"></property>
     </bean>
 </beans>
  @Test
    public void demo1(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        Product product = (Product) applicationContext.getBean("product");
        System.out.println(product.getName());
    }

1.3.4集合属性的注入

package cn.spring3.demo6;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class CollectionDemo {
    private List<String> list;
    private Set<String> set;
    private Map<String, Integer> map;
    private Properties properties;
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Set<String> getSet() {
        return set;
    }
    public void setSet(Set<String> set) {
        this.set = set;
    }
    public Map<String, Integer> getMap() {
        return map;
    }
    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }
    public Properties getProperties() {
        return properties;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

}
<?xml version="1.0" encoding="UTF-8"?>
<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"> 

     <bean id="collectionDemo" class="cn.spring3.demo6.CollectionDemo">
         <property name="list">
             <list >
                 <value>哈哈</value>
                 <value>呵呵</value>
             </list>
         </property>
         <property name="set">
             <set>
                 <value>嘻嘻</value>
                 <value>笨笨</value>
             </set>
         </property>
         <property name="map">
             <map>
                 <entry key="你好" value="1"/>
             </map>
         </property>
         <property name="properties">
             <props>
                 <prop key="哈哈">呵呵</prop>
             </props>
         </property>
     </bean>

 </beans>
package cn.spring3.demo6;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    @Test
    public void demo1(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        CollectionDemo c = (CollectionDemo) applicationContext.getBean("collectionDemo");
        System.out.println(c.getList());
        System.out.println(c.getSet());
        System.out.println(c.getMap());
        System.out.println(c.getProperties());
    }
}

1.3.5加载配置文件

  • 第一种写法:
ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("bean1.xml","bean2.html");
  • 第二种写法
<import resource="applicationContext2.xml"/>

1.4 IOC容器装配Bean(注解方式)

1.4.1Spring的注解装配Bean

package cn.demo1;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserService {

    public void sayHello(){
        System.out.println("Hello World");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <context:component-scan base-package="cn.demo1"/>
</beans>
package cn.demo1;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.sayHello();
    }
}
  • 除了@Component外,Spring提供了3个功能基本和@Component等效的注解。

    • @Repository用于对DAO实现类进行标注
    • @Service用于对Service实现类进行标注
    • @Controller用于对Controller实现类进行标注

  

1.4.2Bean属性的注入

  • 普通属性

    •  @value() 
package cn.demo1;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("userService")
public class UserService {
    @Value("世界")
    private String info;

    public void sayHello(){
        System.out.println("Hello " +info);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <context:component-scan base-package="cn.demo1"/>
</beans>
package cn.demo1;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.sayHello();
    }
}
  • 对象属性

    • @AutoWired:自动装配默认使用类型注入

      • @Qualifier("") 按名称进行注入
    • @Resource等价于@Autowired和@Qualifier(),是按照名称进行注入。      
package cn.demo2;

import org.springframework.stereotype.Repository;

@Repository
public class UserDAO {

    public void show() {
        System.out.println("这是数据访问层");
    }

}
package cn.demo2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserService {
    @Autowired
    private UserDAO userDAO;

    public void show(){
        userDAO.show();
        System.out.println("这是业务层");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <context:component-scan base-package="cn.demo2"/>
</beans>
package cn.demo2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.show();
    }
}
package cn.demo2;

import org.springframework.stereotype.Repository;

@Repository("userDAO")
public class UserDAO {

    public void show() {
        System.out.println("这是数据访问层");
    }

}
package cn.demo2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserService {
    @Autowired
    @Qualifier("userDAO")
    private UserDAO userDAO;

    public void show(){
        userDAO.show();
        System.out.println("这是业务层");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <context:component-scan base-package="cn.demo2"/>
</beans>
package cn.demo2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.show();
    }
}
package cn.demo2;

import org.springframework.stereotype.Repository;

@Repository("userDAO")
public class UserDAO {

    public void show() {
        System.out.println("这是数据访问层");
    }

}
package cn.demo2;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
@Service("userService")
public class UserService {
    @Resource(name="userDAO")
    private UserDAO userDAO;

    public void show(){
        userDAO.show();
        System.out.println("这是业务层");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <context:component-scan base-package="cn.demo2"/>
</beans>
package cn.demo2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.show();
    }
}

1.4.3Bean其他属性的配置

  • 在XML文件配置中配置初始化和销毁方法

    • init-method和destory-method。
  • 在注解中配置初始化和销毁
    • @PostConstruct
    • @PreDestroy 
  • 配置Bean的作用范围

    • @Scope

1.4.4Spring的XML和注解的结合使用

  • XML:bean管理。
  • 注解:注入属性的时候比较方便。
  • 两种方式结合:一般使用XML注册Bean,使用注解进行属性的注入。

1.5 Spring整合web开发

package cn.demo3;

import org.springframework.stereotype.Service;

@Service("userService")
public class UserService {

    public void show(){
        System.out.println("Hello Spring");
    }
}
package cn.demo3;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@SuppressWarnings("serial")
public class UserServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.show();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        this.doGet(request, response);
    }

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

    <context:component-scan base-package="cn"/>
</beans>
  • 正常整合Servlet和Spring是没有问题的
  • 但是每次执行Servlet的时候都会加载Spring配置,加载Spring环境。

  • 解决方法

    • 在Servlet的init方法中加载Spring配置文件,但是这种方法不是很好,因为其他Servlet用不了。
    • 将加载信息内容放到ServletContext域中,ServletContext对象是全局对象,服务器启动的时候创建,在创建ServletContext的时候就加载Spring配置文件,即Spring环境。
      • 使用ServletContextLinstener:用于监听ServletContext对象的创建和销毁的监听器,使用它可以帮助我们完成我们所需要的功能。
      • 庆幸的是,Spring提供了web整合包spring-web-3.2.0.RELEASE.jar就已经帮助我们实现了。
  • 导入jar包:spring-web-3.2.0.RELEASE.jar
    • public class ContextLoaderListener extends ContextLoader implements ServletContextListener {}可以看出实现了ServletContextListener接口。
    • 而Spring默认加载的是WEB-INF下的配置文件,我们可以从XmlWebApplicationContext类中观察到。
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
    public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
    public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
    public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
}
    • 如何修改加载applicationContext.xml的位置,可以观察XmlWebApplicationContext类。 

 

/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
package org.springframework.web.context.support;

import java.io.IOException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
    public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
    public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
    public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        beanDefinitionReader.setEnvironment(getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }

    protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
    }

    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        String[] configLocations = getConfigLocations();
        if (configLocations != null)
            for (String configLocation : configLocations)
                reader.loadBeanDefinitions(configLocation);
    }

    protected String[] getDefaultConfigLocations() {
        if (getNamespace() != null) {
            return new String[] { "/WEB-INF/" + getNamespace() + ".xml" };
        }

        return new String[] { "/WEB-INF/applicationContext.xml" };
    }
}
  • 在web.xml文件中配置如下内容:
<!-- 配置ServletContext监听器,用于服务器一启动就将Spring的配置信息放入ServletContext域对象之中 -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 更改Spring读取applicationContext.xml配置文件的路径 -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

1.6 Spring整合Junit

  • 程序中导入Junit的jar包。
  • 导入一个jar包,Spring与Junit整合的jar包。
    • spring-test-3.2.0.RELEASE.jar。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringTest {
    @Autowired
    private UserService userService;

    @Test
    public void demo1(){
        userService.sayHello();
    }
}

          

最新文章

  1. Meteor + node-imap(nodejs) + mailparser(nodejs) 实现完整收发邮件
  2. java中采用dom4j解析xml文件
  3. ubuntu14.04显卡驱动问题(amd5600k集显7650d)
  4. spring多线程与定时任务
  5. matlab squeeze函数的用法
  6. [OrangePi] If you are using an older image
  7. Data
  8. WPF 之 文本框及密码框添加水印效果
  9. IE9中jquery发生Object未定义原因及解决办法
  10. 设置linux服务器定时与时间服务器同步
  11. IOS--UIAlertView的使用方法详细
  12. MongoDB--数据库与Collection注意事项
  13. 部署ionic开发环境
  14. IE兼容事件绑定V1.0
  15. idea设置JVM运行参数
  16. WinForm版图像编辑小程序(实现图像拖动、缩放、旋转、抠图)
  17. 联想笔记本BIOS设置中文详解
  18. 2014年10月Android面试总结
  19. python线程的GIL问题(全局解释器锁)
  20. js 温故而知新 用typeof 来判断一个未定义的变量

热门文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(85)-Quartz 作业调度用法详解二
  2. javascript精度问题与调整
  3. CSS自定义动画
  4. 快学Scala之继承
  5. SQL 中 decode()函数
  6. Android之IPC(aidl)
  7. Java - static的注意点
  8. 本地存储之cookie、localStorage、sessionStorage
  9. tensorflow Relu激活函数
  10. css的背景background的相关属性