您的位置:首页 > 编程语言 > Java开发

Spring的基本知识(入门)

2017-02-22 20:34 323 查看







1、如何在纯java项目中使用spring

第一步:当然是新建一个java工程了,然后起一个好听的名字,新建的过程就略了吧,相信应该没有朋友不会吧。
第二步:添加所需要的包,你可以把所有的lib文件下的包都添加到你的工程里面去(不要以sources和javadoc结尾的包,这些不要不要!),别忘了一个关键的第三方包,它的名字叫做:commons-loggin-1.1.3.jar。这是一个jar包,是必须要有的,不然会报错
第三部:你可以选择设值注入还是构造注入两种方式来编写你的javabean了。spring将所有的东西都当做bean来操作,这样的好处是低耦合松散耦合,写代码更简单更方便啊。
首先写两个javabean,这两个javabean继承自他们的接口父类。
两个父类
public interface Knight {
public void embarkOnQuest();
}
public interface Quest {

void embark();

}


然后两个javabean实现父类
public class BraveKnight implements Knight{
private Quest quest;
public BraveKnight(Quest quest){
this.quest=quest;
}

public void embarkOnQuest(){
quest.embark();
}

}
public class SlayDragonQuest implements Quest{

public SlayDragonQuest(PrintStream stream) {
super();
this.stream = stream;
}

private PrintStream stream;

@Override
public void embark() {
// TODO Auto-generated method stub
stream.println("Embarking on quest to slay the dragon!");
}

}


接下来就是要在xml文档中配置这两个类了。我们仔细观察,发现我们的勇敢的骑士(BraveKnight)持有一个quest对象的引用,并在构造器中进行了初始化, 这就叫做构造注入了。那么xml中如何构造注入呢?
在src同级下创建一个bean.xml文件,名字随意,这里取名为bean。注意,你在哪里创建的,在写主函数的时候就要修改路径;下面的xml将System.out传给了quest
bean.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="knight" class="cn.nju.fxd.spring.BraveKnight">
<constructor-arg ref="quest"/>
</bean>
<bean id="quest" class="cn.nju.fxd.spring.SlayDragonQuest">
<constructor-arg value="#{T(System).out}" />
</bean>

</beans>


好,下面我们写我们的测试程序,也就是main函数啦。
public class SpringTest {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
BraveKnight braveKnight = (BraveKnight) ctx.getBean("knight",Knight.class);
braveKnight.embarkOnQuest();

}
}


可以看到,我们的main函数里面并没有new一个quest,然后传到bravekinght里面,也没有new 一个knight。这就是spring的神奇之处了,把工厂模式完全整合到spring里面去了,输出的内容是啥?你们自己猜猜看。

2.面向切面编程

上面讲了依赖注入的一个小例子,使用构造器注入,那么什么是面向切面编程呢?面向切面编程往往被定义为促使软件系统实现关注点分离的一项技术,系统由许多不同的组件组成,每一个组件各负责一块特定功能。除了实现自身核心的功能之外,这些组件还经常承担着额外的职责。注入日志、事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去。这些系统服务通常被称为横切关注点,因为他们会跨越系统的多个组件。
如果讲这些关注点分散到多个组件中去,你的代码将会带来双重的复杂性。
(1)实现系统关注点功能的代码将会重复出现在多个组件中。这意味着如果你要改变这些关注点的逻辑,必须修改各个模块的相关实现。
(2)组件会因为那些与自身核心业务无关的代码而变得混乱。一个向地址簿增加地址条目的方法,应该只关注如何添加地址,而不应该关注它是不是安全的或者是否需要支持事物。
面向切面编程将系统服务模块坏,并以声明的方式将他们应用到他们需要影响的组件中去。所造成的的结果就是这些组件会具有更高的内聚性并且会更加关注自身的业务,完全不需要了解涉及系统服务所带来的的复杂性。总之,AOP能够确保POJO的简单性。

回到上面的例子,我们为我们上面的骑士增加一个记录者--吟游诗人。吟游诗人会记录骑士的勇敢事迹并进行传唱,我们创建一个Minstrel类,

public class Minstrel {
public Minstrel(PrintStream stream) {
super();
this.stream = stream;
}

private PrintStream stream;

public void singBeforeQuest(){
stream.println("Fa la la,the knight is so brave!");
}

public void singAfterQuest(){
stream.println("Tee hee hee,the brave knight did embark on a quest!");
}

}
正如你所看到的,Minstrel只有两个方法,singBeforeQuest方法在执行探险前被执行,singAfterQuest在执行探险后被调用,PrintSteam的引用出爱用构造器注入实现。

同时,BraveKnight如果要调用吟游诗人两个方法, 一般的思路是让吟游诗人加入到BraveKnight中去,成为它的一个成员变量即可,但是,按照面向对象的想法,BraveKnight针对需要一个吟游诗人吗?或者说,吟游诗人属不属于某个骑士呢?答案是确定的,吟游诗人不属于某个骑士。

我们可以将Minstrel声明为一个切面,在bean.xml中添加一个新bean,bean的class为Minstrel,并添加一个切面,如下:

<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> 
<bean id="knight" class="cn.nju.fxd.spring.BraveKnight">
<constructor-arg ref="quest"/>
</bean>
<bean id="quest" class="cn.nju.fxd.spring.SlayDragonQuest">
<constructor-arg value="#{T(System).out}" />
</bean>
<bean id="minstrel" class="cn.nju.fxd.spring.Minstrel">
<constructor-arg value="#{T(System).out}"/>
</bean>

<aop:config>
<aop:aspect ref="minstrel">
<!-- 定义切点为embarkOnQuest方法 -->
<aop:pointcut expression="execution(* *.embarkOnQuest(..))" id="embark"/>
<aop:before method="singBeforeQuest" pointcut-ref="embark"/>
<aop:after method="singAfterQuest" pointcut-ref="embark"/>
</aop:aspect>

</aop:config>

</beans>
当然光实现上面那样是不行的,你需要额外的第三方包支持,哪几个呢?aopalliandce-alpha1.jar,aspectjrt.jar,aspectjweaver.jar另外要切记,千万注意大小写和拼写错误!!

3.容纳你的bean--spring容器

在基于Spring的应用中,你的应用对象生存于spring容器中,容器负责创建对象,装配他们,配置并管理他们的整个生命周期,从生存到死亡。spring容器并不是只有1个,spring自带了多个容器的实现,可以归为两种不同的类型。bean工厂类型是最简单的容器,提供基本的DI支持。应用上下文容器基于BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。

3.1使用应用上下文

spring自带了多种类型的应用上下文,下面的几个可能是你最有可能遇到的。
(1)AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载spring应用上下文
(2)AnnotationConfigWebApplication:从一个或多个基于java的配置类中加载Spring Web应用上下文。
(3)ClassPathXmlApplicationContext:从类路径下的一个或者多个xml配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。
(4)FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义
(5)XmlWebApplicationContext:从Web应用下的一个或多个xml配置文件中加载上下文定义。
我们前面已经使用过ClassPathApplicationContext了。

3.2bean的生命周期

spring容器中的bean生命周期要比传统java应用的bean要复杂的多。



如上图所示,bean继续之前,bean工厂执行了若干的启动步骤,上图步骤详细描述如下:
(1)spring对bean进行实例化
(2)spring将值和bean的引用注入到bean对应的属性中;
(3)如果bean实现了BeanNameAware接口,spring将bean的id传递个setBean-Name()方法;
(4)如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
(5)如果bean实现了ApplicationContextAware接口,spring将调用setApplicationContext()。
(6)如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法;

(7)如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。类似地,如果bean使用init-method声明了初始化方法,该方法也会被调用;

(8)如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法;

(9)此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;

(10)如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。

3俯瞰Spring风景线

3.1Spring模块

当我们下载Spring发布版本并查看其lib目录时,会发现里面有多个JAR文件。在Spring
4.0中,Spring框架的发布版本包括了20个不同的模块,每个模块会有3个JAR文件(二进制类库、源码的JAR文件以及JavaDoc的JAR文件)
这些模块依据其所属的功能可以划分为6类不同的功能,如图1.7所示



Spring核心容器

容器是Spring框架最核心的部分,它管理着Spring应用中bean的创建、配置和管理。在该模块中,包括了Spring
bean工厂,它为Spring提供了DI的功能。基于bean工厂,我们还会发现有多种Spring应用上下文的实现,每一种都提供了配置Spring的不同方式。除了bean工厂和应用上下文,该模块也提供了许多企业服务,例如E-mail、JNDI访问、EJB集成和调度。 

Spring的AOP模块

在AOP模块中,Spring对面向切面编程提供了丰富的支持。这个模块是Spring应用系统中开发切面的基础。与DI一样,AOP可以帮助应用对象解耦。借助于AOP,可以将遍布系统的关注点(例如事务和安全)从它们所应用的对象中解耦出来。

数据访问与集成使用

使用JDBC编写代码通常会导致大量的样板式代码,例如获得数据库连接、创建语句、处理结果集到最后关闭数据库连接。Spring的JDBC和DAO(Data
Access Object)模块抽象了这些样板式代码,使我们的数据库代码变得简单明了,还可以避免因为关闭数据库资源失败而引发的问题。该模块在多种数据库服务的错误信息之上构建了一个语义丰富的异常层,以后我们再也不需要解释那些隐晦专有的SQL错误信息了!对于那些更喜欢ORM(Object-Relational
Mapping)工具而不愿意直接使用JDBC的开发者,Spring提供了ORM模块。Spring的ORM模块建立在对DAO的支持之上,并为多个ORM框架提供了一种构建DAO的简便方式。Spring没有尝试去创建自己的ORM解决方案,而是对许多流行的ORM框架进行了集成,包括Hibernate、Java
Persisternce API、Java Data Object和iBATISSQL Maps。Spring的事务管理支持所有的ORM框架以及JDBC。

Web与远程调用

MVC(Model-View-Controller)模式是一种普遍被接受的构建Web应用的方法,它可以帮助用户将界面逻辑与应用逻辑分离。Java从来不缺少MVC框架,Apache的Struts、JSF、WebWork和Tapestry都是可选的最流行的MVC框架。虽然Spring能够与多种流行的MVC框架进行集成,但它的Web和远程调用模块自带了一个强大

的MVC框架,有助于在Web层提升应用的松耦合水平。

Instrumentation

Spring的Instrumentation模块提供了为JVM添加代理(agent)的功能。具体来讲,它为Tomcat提供了一个织入代理,能够为Tomcat传递类文件,就像这些文件是被类加载器加载的一样。如果这听起来有点难以理解,不必对此过于担心。这个模块所提供的Instrumentation使用场景非常有限

测试

鉴于开发者自测的重要性,Spring提供了测试模块以致力于Spring应用的测试。通过该模块,你会发现Spring为使用JNDI、Servlet和Portlet编写单元测试提供了一系列的mock对象实现。对于集成测试,该模块为加载Spring应用上下文中的bean集合以及与Spring上下文中的bean进行交互提供了支持。

3.2 Spring Portfolio

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: