Spring

一、Spring基础
1. Spring简介
  Spring是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最初由 Rod Johnson 和 Juergen Hoeller等开发。Spring是为了解决企业应用程序开发复杂性而创建,框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。
  Spring为企业应用的开发提供一个轻量级的解决方案,该方案包括:基于依赖注入的核心机制,基于AOP的声明式事务管理,与多种持久层技术的整合,以及优秀的Web MVC框架等。可以说,Spring是企业应用开发的“一站式”选择,Spring贯穿表现层、业务层、持久层、然而,Spring并不想取代那些已有的框架,而是以高度的开放性与它们无缝整合。

2. Spring的特点
  1)方便解耦,简化开发
    通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
  2)AOP编程的支持
    通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
  3)声明式事务的支持
    在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
  4)方便程序的测试
    可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。
  5)方便集成各种优秀框架
    Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。
  6)降低Java EE API的使用难度
    Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。
  7)Java 源码是经典学习范例
    Spring的源码设计精妙、结构清晰、匠心独用,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。

3. Spring的组成
  1)核心容器(Spring Core):
    核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  2)Spring 上下文:
    Spring 上下文是一个配置文件,向Spring框架提供上下文信息。Spring 上下文包括企业服务,例如JNDI、EJB、电子邮件、国际化、校验和调度功能。
  3)Spring AOP:
    通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  4)Spring DAO:
    JDBCDAO抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  5)Spring ORM:
    Spring 框架插入了若干个ORM框架,从而提供了 ORM 的对象关系工具,其中包括JDO、Hibernate和iBatisSQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  6)Spring Web 模块:
    Web上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  7)Spring MVC 框架:
    MVC框架是一个全功能的构建 Web应用程序的 MVC 实现。通过策略接口,MVC框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。模型由javabean构成,存放于Map;视图是一个接口,负责显示模型;控制器表示逻辑代码,是Controller的实现。Spring框架的功能可以用在任何J2EE服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同J2EE 环境(Web 或EJB)、独立应用程序、测试环境之间重用。

4. Spring 3.0与以前版本相比的一些变化
  1)Spring3.0不再提供完整的打包文件spring.jar,而是由20个JAR组成。
  2)Spring3.0不再提供依赖包with-dependencies的下载。
  3)Spring3.0已经完全采用Java5进行开发和编译,不再支持Java1.4及以前的版本。
  4)Spring3.0增加EL表达式语言的支持。
  5)Spring3.0可以使用Java类配置来代替XML配置。

5. Spring的下载
  Spring 不再提供单独的 zip 包下载,可以用 maven 或 gradle 下载,或者直接到 http://mvnrepository.com/artifact/org.springframework  、CSDN上去找。本实例采用Spring3.0.5,下载包括spring-framework-3.0.5.RELEASE-with-docs.zip(Spring框架和文档)和spring-framework-3.0.5.RELEASE-dependencies.zip(Spring框架的依赖JAR包),这些包都可以从CSDN上面找到。

二、Spring的依赖注入
1. 依赖注入简介
  如上,程序并不用主动设置PersonService实例的name属性值,而是通过Spring配置文件配置,这就是说,PersonService实例的属性值并不是程序主动设置的,而是由Spring容器来负责注入的。在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,因此称为控制反转(IoC)。创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
  使用依赖注入,不仅可以为Bean注入普通的属性值,还可以注入其它Bean的引用。通过这种依赖注入,Java EE应用中的各种组件不需要以硬编码方式耦合在一起,甚至无须使用工厂模式。可见,依赖注入是目前最优秀的解耦方式,依赖注入让Spring的Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起。

2. 依赖注入示例一:设值注入
  IoC容器使用属性的setter方法来注入被依赖的实例(常用)。
  1)导入Spring框架
  将spring-framework-3.0.5.RELEASE-with-docs.zip里dist路径下的全部JAR包和spring-framework-3.0.5.RELEASE-dependencies.zip里所需的包导入到项目中
  2)接口PersonService.java
package test;
public interface PersonService {
    public void testPerson();
}

  3)实现类PersonServiceImpl.java
package test;
public class PersonServiceImpl implements PersonService{
    private PersonDao personDao;
    public void setPersonDao(PersonDao personDao) {
        this.personDao = personDao;
    }
    public void testPerson() {
        System.out.println("注入:" + personDao.testPerson());
    }
}

  4)接口PersonDao.java
package test;
public interface PersonDao {
    public String testPerson();
}

  5)实现类PersonDaoImpl.java
package test;
public class PersonDaoImpl implements PersonDao {
    public String testPerson() {
        return "依赖注入就是控制反转";
    }
}

  6)Spring配置文件bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!-- 将PersonService类部署成Spring容器中的Bean  -->
    <bean id="personService" class="test.PersonServiceImpl">
        <property name="personDao" ref="personDao"/>
    </bean>
    <bean id="personDao" class="test.PersonDaoImpl"></bean>
</beans>

  7)测试类TestSpring.java
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring {
    public static void main(String[] args) {
        // 创建Spring容器,一旦获得了该容器,就可通过该容器访问Spring容器中的Bean
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        System.out.println(ctx);
        PersonServiceImpl p = ctx.getBean("personService" , PersonServiceImpl.class);
        p.testPerson();   
    }
}


3. 注入方式二:构造注入
  Ioc容器使用构造器来注入被依赖的实例。
  1)实现类PersonServiceImpl.java
package test;
public class PersonServiceImpl implements PersonService{
    private PersonDao personDao;
    // 构造注入所需的带参数的构造器
    public PersonServiceImpl(PersonDao personDao) {
        this.personDao = personDao;
    }
    public void testPerson() {
        System.out.println("注入:" + personDao.testPerson());
    }
}

  2)Spring配置文件bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <!-- 将PersonService类部署成Spring容器中的Bean  -->
    <bean id="personService" class="test.PersonServiceImpl">
        <!-- 使用构造注入 -->
        <constructor-arg ref="personDao"/>
    </bean>
    <bean id="personDao" class="test.PersonDaoImpl"></bean>
</beans>

  3)其它同上面的设值注入

三、Spring的AOP
1. AOP简介
  因为软件系统需求变更是很频繁的事情,系统可能对前期设计的方法进行不断的更改,如增加事务控制、合法性验证、记录日志等。我们希望有一种特殊的方法,我们只要定义该方法,无须在原方法中显示调用它,系统会自动执行该特殊方法。这就是AOP,它专门用于处理系统中分布于各个模块中的交叉关注点的问题,处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。

2. AspectJ对AOP的实现
  AspectJ是一个基于Java语言的AOP框架,是Eclipse下面的一个开源子项目,主要包括两部分:第一部分定义了如何表达、定义AOP编程中的语法规范;另一部分是工具部分,包括编译、调试工具等。
  1)下载和安装AspectJ
     登陆http://www.eclipse.org/aspectj/downloads.php#stable_release下载AspectJ的最新版本
    AspectJ安装:启动命令行窗口,进入刚下载的aspectj-1.6.10.jar文件所在路径,输入如下命令:java -jar aspectj-1.6.10.jar,在弹出窗口中点击 Next --> 选择jdk安装路径 Next --> 选择安装目录 Install --> Next --> Finish。
    在Path环境变量中添加 ...\aspectj1.6\bin,在CLASSPATH环境变量中添加 ...\aspectj1.6\lib\aspectjrt.jar。

  2)AspectJ基本使用
      a.定义一个Java类 Hello.java
package lee;
public class Hello {
    //定义一个简单方法,模拟应用中的业务逻辑方法
    public void sayHello(){
        System.out.println("Hello AspectJ!");
    }
    public static void main(String[] args){
        Hello h = new Hello();
        h.sayHello();
    }
}

    b.定义一个特殊的Java类(但并不是一个Java类),需要在执行sayHello()方法前启动事务,方法执行结束时关闭事务。
package lee;
public aspect TxAspect{
    //指定执行Hello.sayHello()方法时执行下面代码块
    void around():call(void Hello.sayHello()){
        System.out.println("开始事务...");
        proceed(); // 调用原来的sayHello()方法
        System.out.println("事务结束...");
    }
}

    c.再定义一个特殊的Java类,在执行sayHello()方法后记录日志。
package lee;
public aspect LogAspect {
    //定义一个PointCut,其名为logPointcut
    //该PointCut对应于指定Hello对象的sayHello方法
    pointcut logPointcut() :execution(void Hello.sayHello());
    //在logPointcut之后执行下面代码块
    after():logPointcut(){
        System.out.println("记录日志...");
    }
}

    注意:Java无法识别TxAspect.java文件的内容,所以我们要使用ajc.exe命令来编译上面的java内容:ajc -d . hello.java TxAspect.java。

3.Spring的AOP支持
  AOP从程序运行角度考虑程序的流程,提取业务处理过程的切面。AOP面向的是程序运行中各个步骤,希望以更好的方式来组合业务处理的各个步骤。框架具有两个特征:各步骤之间的良好隔离性;源代码无关性。
  Spring中AOP代理由Spring的IoC容器负责生成、管理,因此AOP代理可以直接使用容器中的其它Bean实例作为目标。Spring AOP使用纯Java实现,它不需要专门的编译过程,目前只支持将方法调用作为连接点。
  1)基于Annotation的零配置方式
    a.定义一个Service接口
package test.service;
public interface Person {
    public String sayHello(String name);
    public void eat(String food);
}

    b.实现Service接口
package test.service.impl;
import org.springframework.stereotype.*;
import test.service.Person;
@Component
public class Chinese implements Person {
    public String sayHello(String name) {
        return name + " Hello , Spring AOP";
    }
    public void eat(String food) {
        System.out.println("我正在吃:" + food);
    }
}

    c.配置Spring配置文件 bean.xml
<?xml version="1.0" encoding="GBK"?>
<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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <!-- 指定自动搜索Bean组件、自动搜索切面类 -->
    <context:component-scan base-package="test.service,test.advice">
        <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
    </context:component-scan>
    <!-- 启动@AspectJ支持 -->
    <aop:aspectj-autoproxy/>
</beans>

    d.定义一个用于Before增强处理的切面
package test.advice;
import org.aspectj.lang.annotation.*;
//定义一个切面
@Aspect
public class BeforeAdviceTest {
    // 匹配test.service.impl包下所有类的、所有方法的执行作为切入点
    @Before("execution(* test.service.impl.*.*(..))")
    public void authority() {
        System.out.println("1.模拟执行权限检查");
    }
}

    e.测试
package test;
import org.springframework.context.*;
import org.springframework.context.support.*;
import test.service.*;
public class BeanTest {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        Person p = ctx.getBean("chinese", Person.class);
        System.out.println(p.sayHello("张三"));
        p.eat("西瓜");
    }
}

    f.其它处理类型切面
        AfterReturning增强处理:目标方法正常完成后被织入;
        AfterThrowing增强处理:处理程序中未处理的异常;
        After增强处理:目标方法正常和非正常结束都执行;
        Around增强处理:等于Before增强处理和AfterReturning增强处理的总和;

  2)基于XML配置文件的管理方式
    a.定义切面类1,Bean类同上
package test.advice;
import org.aspectj.lang.*;
import java.util.Arrays;
public class FourAdviceTest {
    public Object processTx(ProceedingJoinPoint jp) throws java.lang.Throwable {
        System.out.println("Around增强:执行目标方法之前,模拟开始事务...");
        // 访问执行目标方法的参数
        Object[] args = jp.getArgs();
        // 当执行目标方法的参数存在,
        // 且第一个参数是字符串参数
        if (args != null && args.length > 0
                && args[0].getClass() == String.class) {
            // 改变第一个目标方法的第一个参数
            args[0] = "被改变的参数";
        }
        // 执行目标方法,并保存目标方法执行后的返回值
        Object rvt = jp.proceed(args);
        System.out.println("Around增强:执行目标方法之后,模拟结束事务...");
        return rvt + " 新增的内容";
    }

    public void authority(JoinPoint jp) {
        System.out.println("②Before增强:模拟执行权限检查");
        // 返回被织入增强处理的目标方法
        System.out.println("②Before增强:被织入增强处理的目标方法为:"
                + jp.getSignature().getName());
        // 访问执行目标方法的参数
        System.out.println("②Before增强:目标方法的参数为:"
                + Arrays.toString(jp.getArgs()));
        // 访问被增强处理的目标对象
        System.out.println("②Before增强:被织入增强处理的目标对象为:" + jp.getTarget());
    }

    public void log(JoinPoint jp, Object rvt) {
        System.out.println("AfterReturning增强:获取目标方法返回值:" + rvt);
        System.out.println("AfterReturning增强:模拟记录日志功能...");
        // 返回被织入增强处理的目标方法
        System.out.println("AfterReturning增强:被织入增强处理的目标方法为:"
                + jp.getSignature().getName());
        // 访问执行目标方法的参数
        System.out.println("AfterReturning增强:目标方法的参数为:"
                + Arrays.toString(jp.getArgs()));
        // 访问被增强处理的目标对象
        System.out.println("AfterReturning增强:被织入增强处理的目标对象为:" + jp.getTarget());
    }

    public void release(JoinPoint jp) {
        System.out.println("After增强:模拟方法结束后的释放资源...");
        // 返回被织入增强处理的目标方法
        System.out.println("After增强:被织入增强处理的目标方法为:"
                + jp.getSignature().getName());
        // 访问执行目标方法的参数
        System.out.println("After增强:目标方法的参数为:" + Arrays.toString(jp.getArgs()));
        // 访问被增强处理的目标对象
        System.out.println("After增强:被织入增强处理的目标对象为:" + jp.getTarget());
    }
}

    b.定义切面类2
package test.advice;
public class SecondAdviceTest {
    // 定义Before增强处理
    public void authority(String aa) {
        System.out.println("目标方法的参数为:" + aa);
        System.out.println("①号Before增强:模拟执行权限检查");
    }
}

    c.Spring配置文件
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <aop:config>
        <!-- 将fourAdviceBean转换成切面Bean
            切面Bean的新名称为:fourAdviceAspect
            指定该切面的优先级为2 -->
        <aop:aspect id="fourAdviceAspect" ref="fourAdviceBean"
            order="2">
            <!-- 定义一个After增强处理,
                直接指定切入点表达式
                以切面Bean中的release()方法作为增强处理方法 -->
            <aop:after pointcut="execution(* org.crazyit.app.service.impl.*.*(..))"
                method="release"/>
            <!-- 定义一个Before增强处理,
                直接指定切入点表达式
                以切面Bean中的authority()方法作为增强处理方法 -->
            <aop:before pointcut="execution(* org.crazyit.app.service.impl.*.*(..))"
                method="authority"/>
            <!-- 定义一个AfterReturning增强处理,
                直接指定切入点表达式
                以切面Bean中的log()方法作为增强处理方法 -->
            <aop:after-returning pointcut="execution(* org.crazyit.app.service.impl.*.*(..))"
                method="log" returning="rvt"/>
            <!-- 定义一个Around增强处理,
                直接指定切入点表达式
                以切面Bean中的processTx()方法作为增强处理方法 -->
            <aop:around pointcut="execution(* org.crazyit.app.service.impl.*.*(..))"
                method="processTx"/>
        </aop:aspect>

        <!-- 将secondAdviceBean转换成切面Bean
            切面Bean的新名称为:secondAdviceAspect
            指定该切面的优先级为1,该切面里的增强处理将被优先织入 -->
        <aop:aspect id="secondAdviceAspect" ref="secondAdviceBean"
            order="1">
            <!-- 定义一个Before增强处理,
                直接指定切入点表达式
                以切面Bean中的authority()方法作为增强处理方法
                且该参数必须为String类型(由authority方法声明中msg参数的类型决定) -->
            <aop:before pointcut="execution(* org.crazyit.app.service.impl.*.*(..)) and args(aa)"
                method="authority"/>
        </aop:aspect>
    </aop:config>
    <!-- 定义一个普通组件Bean -->
    <bean id="chinese"
    class="org.crazyit.app.service.impl.Chinese"/>
    <!-- 定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
    <bean id="fourAdviceBean"
    class="org.crazyit.app.advice.FourAdviceTest"/>
    <!-- 再定义一个普通Bean实例,该Bean实例将被作为Aspect Bean -->
    <bean id="secondAdviceBean"
    class="org.crazyit.app.advice.SecondAdviceTest"/>
</beans> 


四、Spring的零配置(Annotation)
  如今,几乎所有的主流Java框架都打算支持”零配置“,包括Struts2、Hibernate,以及现在要说的Spring,都开始支持使用Annotation来代替XML配置文件了。
1. 搜索Bean类
  既然我们不再使用Spring配置文件来配置任何Bean实例,那么我们只能指望Spring会自动搜索某些路径下的Java类,并将这些类注册成Bean实例。Spring提供了如下几个Annotation来标注Spring Bean:
    1)@Component:标注一个普通的Spring Bean类
    2)@Controller:标注一个控制器组件类
    3)@Service:标注一个业务逻辑组件类
    4)@Repository:标注一个DAO组件类
  如果我们需要定义一个普通的Spring Bean类,则直接使用@Component标注即可。但如果用@Controller、@Service、@Repository来标注这些Bean类,这些Bean类将被作为特殊的Java EE组件对待,也许能更好地被工具处理,或与切面进行关联。在未来的语义中也许还能携带更多的语义,所以我们应尽量使用后三个标注我们的Bean类。
  在这种基于Annotation的方式下,Spring采用约定的方式来为这些Bean实例指定名称,默认是Bean类的首字母小写,其它部分不变。当然,Spring也允许在使用@Component标注时指定Bean实例的名称,如下:
    @Component("beanName")

  接下来需要在Spring的配置文件中指定搜索路径,Spring将会自动搜索该路径下的所有Java类,并根据这些Java类来创建Bean实例。配置如下:
<?xml version="1.0" encoding="GBK"?>
<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.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!-- 自动扫描指定包及其子包下的所有Bean类 -->
    <context:component-scan base-package="com.jiang.service"/>
</beans> 


  除了上面的方法外,我们还可以通过<component-scan .../>元素添加<include-filter .../>(指定满足该规则的Java类会被当成Bean类来处理)或<exclude-filter.../>(指定满足该规则的Java类不会被当成Bean类来处理)子元素来指定Spring Bean类,只要位于指定路径下的Java类满足这种规则,即使这些Java类没有使用任何Annotation标注,Spring一样会将它们当成Bean类来处理。配置如下:
<?xml version="1.0" encoding="GBK"?>
<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.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!-- 自动扫描指定包及其子包下的所有Bean类 -->
    <context:component-scan base-package="test"/>
    <!-- 只包含以ServiceImpl、DaoImpl结尾的类,满足此条件时就算没有注解也会被当成Bean处理
    <context:component-scan
        base-package="com.jiang.service">
        <context:include-filter type="regex"
            expression=".*ServiceImpl"/>
        <context:include-filter type="regex"
            expression=".*DaoImpl"/>
    </context:component-scan>
     -->
</beans>


2. 指定Bean的作用域
  当使用XML配置方式来配置Bean实例时,可以通过scope来指定Bean实例的作用域,没有指定scope属性的Bean实例的作用域默认是singleton。如下:
    @Scope("prototype")
    @Component("beanName")
    public class xxx {...}

  Spring支持以下5种作用域:
    1)singleton:单例模式,在整个Spring IoC窗口中,使用singleton定义的Bean将只有一个实例。
    2)prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。
    3)request:对于每次HTTP请求,使用request定义的Bean都上将产生一个新实例,故只有在Web应用中才真正有效。
    4)session:对于每次HTTP Session,使用session定义的Bean都将产生一个新的实例,同样只有在Web应用中才真正有效。
    5)global session:每个全局的HTTP Session对应一个Bean实例,仅在使用portlet context的时候有效。

3. 使用@Resource配置依赖
  @Resource与<property.../>元素的ref属性有相同的效果。
  1)修饰setter方法:
    private Test test;
    //设值注入所需的setter方法
    @Resource(name="testName") 
    public void setTest(Test test){
      this.test = test;
    }

  上面定义了一个@Resource Annotation,该Annotation指定将testName注入该setTest()方法,也就是将容器中的testName Bean作为setTest()方法的参数传入。此时省略name属性注入的是为test的Bean。

  2)直接修饰Field
    @Resource(name="testName") 
    private Test test;

  如上,使用@Resource修饰Field将会更加简单,连setter()方法都可以不要。此时省略name属性注入的是与该Field同名的Bean,也为test。

4. 使用@PostConstruct和@PreDestroy定制生命周期行为
  @PostConstruct和@PreDestroy都用于修饰方法,无需任何属性。其中前者修饰的方法是Bean的初始化方法,Spring容器将会在Bean的依赖关系注入完成后回调该方法。后者修饰的方法是Spring容器在销毁Bean之前的方法。

5. 使用@DependsOn和@Lazy
  @DependsOn可以修饰Bean类或方法,使用该Annotation时可以指定一个字符串数组作为参数,每个数组元素对应于一个强制初始化的Bean。如下:
    @DepensOn({"testOne","testTwo"})
    @Component
    public class Test{...}
  上面的代码指定在初始化Test Bean之前,会强制初始化testOne、testTwo两个Bean。
  @Lazy主要用于修饰Spring Bean类,用于指定该Bean的预初始化行为,使用时可指定一个boolean型的value属性,该属性决定是否预初始化该Bean。如下:
    @Lazy(true)
    @Component
    public class Test{...} 
  上面的代码指定在初始化Test Bean时,不会预初始化Test Bean。

6. 使用@AutoWired和@Qualifier
  Spring提供了@AutoWired来指定自动装配,它可以标注setter方法、普通方法、Field和构造器等。如下:
    @AutoWired
    public void setTest(Test test){
      this.test = test;
    }   
  上面对setTest方法进行了自动装配,此时Spring会自动搜索容器中类型为Test的Bean实例,并将该Bean实例作为 setTest方法的参数传入。

  为了实现精确的自动装配,Spring提供了@Qualifier根据Bean标识来指定自动装配,如下:
    @Autowired
    @Qualifier("testName")
    private Test test;
  上面的配置指定了test Field将使用自动装配,且精确指定了被装配的Bean实例名称是testName,这意味着将会搜索容器中名为testName的Test实例,并将该实例注入test Field。

五、Spring jar包简介
  org.springframework.aop- 3.0.0.RELEASE--------------------Spring的面向切面编程,提供AOP(面向切面编程)实现
  org.springframework.asm- 3.0.0.RELEASE--------------------Spring独立的asm程序,相遇Spring2.5.6的时候需要asmJar 包.3.0开始提供他自己独立r asmJar
  org.springframework.aspects- 3.0.0.RELEASE--------------------Spring提供对AspectJ框架的整合\
  org.springframework.beans- 3.0.0.RELEASE--------------------SpringIoC(依赖注入)的基础实现
  org.springframework.context.support- 3.0.0.RELEASE--------------------Spring-context的扩展支持,用于MVC方面
  org.springframework.context- 3.0.0.RELEASE--------------------Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等
  org.springframework.core- 3.0.0.RELEASE--------------------Spring3.0的核心工具包
  org.springframework.expression- 3.0.0.RELEASE--------------------Spring表达式语言
  org.springframework.instrument.tomcat- 3.0.0.RELEASE--------------------Spring3.0对Tomcat的连接池的集成
  org.springframework.instrument- 3.0.0.RELEASE--------------------Spring3.0对服务器的代理接口
  org.springframework.jdbc- 3.0.0.RELEASE--------------------对JDBC的简单封装
  org.springframework.jms- 3.0.0.RELEASE--------------------为简化JMS API的使用而作的简单封装
  org.springframework.orm- 3.0.0.RELEASE--------------------整合第三方的ORM框架,如hibernate,ibatis,jdo,以及spring的JPA实现
  org.springframework.oxm-3.0.0.RELEASE--------------------Spring 对Object/XMl的映射支持,可以让Java与XML之间来回切换
  org.springframework.test- 3.0.0.RELEASE--------------------对Junit等测试框架的简单封装
  org.springframework.transaction- 3.0.0.RELEASE--------------------为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理
  org.springframework.web.portlet- 3.0.0.RELEASE--------------------SpringMVC的增强
  org.springframework.web.servlet- 3.0.0.RELEASE--------------------对JEE6.0 Servlet3.0的支持
  org.springframework.web.struts- 3.0.0.RELEASE--------------------整合Struts的时候的支持
  org.springframework.web- 3.0.0.RELEASE--------------------SpringWeb下的工具包

你可能感兴趣的:(Spring包简介,Spring零配置,Spring概述,Spring示例,Spring依赖注入)