Spring

[b]一、Spring基础[/b]
[b]1. Spring简介[/b]
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并不想取代那些已有的框架,而是以高度的开放性与它们无缝整合。

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

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

[b]4. Spring 3.0与以前版本相比的一些变化[/b]
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配置。

[b]5. Spring的下载[/b]
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上面找到。

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

[b]2. 依赖注入示例一:设值注入[/b]
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();
}
}


[b]3. 注入方式二:构造注入[/b]
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)其它同上面的设值注入

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

[b]2. AspectJ对AOP的实现[/b]
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。

[b]3.Spring的AOP支持[/b]
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>


[b]四、Spring的零配置(Annotation)[/b]
如今,几乎所有的主流Java框架都打算支持”零配置“,包括Struts2、Hibernate,以及现在要说的Spring,都开始支持使用Annotation来代替XML配置文件了。
[b]1. 搜索Bean类[/b]
既然我们不再使用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>


[b]2. 指定Bean的作用域[/b]
当使用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的时候有效。

[b]3. 使用@Resource配置依赖[/b]
@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。

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

[b]5. 使用@DependsOn和@Lazy[/b]
@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。

[b]6. 使用@AutoWired和@Qualifier[/b]
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。

[b]五、Spring jar包简介[/b]
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下的工具包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值