Spring深入浅出教程

Spring深入浅出教程
Spring深入浅出教程

一、理论知识

1.依赖注入、控制反转

依赖注入:在运行期,由外部容器动态地将依赖对象注入到组件中

控制反转:应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部窗口负责得。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓的反转。

2.spring 的主要特性。

(1)降低组件之间的耦合度,实现软件各层之间的解耦。

(2)可以使用容器提供的众多服务,如:事务管理服务、消息服务、JMS 服务、持久化服务等等。

(3)容器提供单例模式支持,开发人员不再需要自己编写实现代码。

(4)容器提供了AOP 技术,利用它很容易实现如权限拦截,运行期监控等功能。

(5)容器提供的众多辅作类,使用这些类能够加快应用的开发,如:JdbcTemplate、HibernateTemplate.

(6)对主流的应用框架提供了集成支持。

3.常用技术

控制反转/依赖注入---面向切入编程---与主流框架的整合、管理---

二、基本实例

1.准备搭建环境

dist\spring.jar

lib\jakata-commons\commons-loggin.jar

如果使用了切面编程,还需下列jar 文件:

lib\aspectj\aspectjweaver.jar 和aspectjrt.jar

lib\cglib\cglib-nodep-2.1.3.jar

如果使用了jsr-250 中的注解,还需要下列jar 文件:

lib\j2ee\common-annotations.jar

2.搭建并测试环境

建立名为spring_01_base项目,根据需求导入jar包。建立一个Junit测试单元SpringEnvTest,测试代码如下:

@Test

public void testEnv() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beans.xml");

}

beans.xml 配置文件在此省略(见下)。运行此测试如无错,则说明环境搭建成功。

说明:beans.xml 可以在类路径下进行配置,也可以在具体的目录下配置。可以是一个配置文件,也可以是多个配置文件组成String 数组传入。

3.实例

作如下准备工作:(1)建立UseDao接口,代码如下:

package com.asm.dao;

public interface UserDao {

void save();

}

(2)建立UserDao接口的实现类,UserDaoImpl

package com.asm.dao.impl;

import https://www.360docs.net/doc/78100657.html,erDao;

public class UserDaoImpl implements UserDao{

public void save() {

System.out.println("执行save方法...");

}

}

(3)在src目录下配置此beans.xml,它的配置如下:

xmlns:xsi="https://www.360docs.net/doc/78100657.html,/2001/XMLSchema-instance"

xsi:schemaLocation="https://www.360docs.net/doc/78100657.html,/schema/beans

https://www.360docs.net/doc/78100657.html,/schema/beans/spring-beans-2.5.xsd">

说明:bean 代表一个实质的java 类,通过它的id 可以获取一个此类的一个对象。

补充:让xml 配置文件在编译时提示

[windows][preferences][myeclipse][files and editors][xml][xml catalog] 点add,在出现窗口的location 中选“file system”,然后在spring 解压目录的dist/resources 目录中选择“spring-beans-2.5.xsd”,并将key Type 值改为“Schema Location”,key 值为:https://www.360docs.net/doc/78100657.html,/schema/beans/spring-beans-2.5.xsd

(4)Junit 测试单元SpringEnvTest 中增加如下代码测试:

@Test

public void base() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beans.xml");

UserDao userDao = (UserDao) ctx.getBean("userDaoImpl");

userDao.save();

}

以上的代码就是通过配置文件beans.xml 获取所需要的实例对象。

4.三种bean 的生成方式

除了上面使用的类直接生成方式,还有bean 静态工厂及bean 实例工厂。

bean 静态工厂的配置如下:

相应的工厂类代码如下:

package com.asm.dao.impl;

public class UserDaoImplFactory {

public static UserDaoImpl getUserDaoImpl(){

return new UserDaoImpl();

}

}

bean实例工厂的配置如下:

factory-method="getUserDaoImpl"/>

相应的工厂类的代码如下:

package com.asm.dao.impl;

public class UserDaoImplFactory2 {

public UserDaoImpl getUserDaoImpl() {

return new UserDaoImpl();

}

}

5.bean 的作用域

singleton:返回bean 的同一个实例,也是默认的作用域(无状态bean使用此作用域)prototype:每次请求都会创建一个实例(有状态bean 使用此作用域)

request、session、global session 这三个作用域主要用在web 应用中

6.bean 的生命周期

(1)什么时候初始化bean 实例

当scope=singleton,即默认情况,会在装载配置文件时实例化。如果希望在调用getBean 时才初始化,可以使用lazy-init="true" 补充:如果希望希望该配置文件中的所有bean 都延迟初始化,则应在beans根结点中使用lazy-init="true"。

当scope=prototype 时,在调用getBean()方法时才会初始化。

(2)生命周期:

构造器、init 方法、获取bean 后的操作、destroy 方法(ctx.close、注意如果bean 的scope 设为prototype 时,当ctx.close 时,destroy 方法不会被调用)

7.属性注入Setter 方式

(1)简单属性(如String):

(2)对象属性-外部bean 注入:在上面的中增加如下配置:

对象属性-内部bean注入:在上面的中增加如下配置:

(3)集合属性注入:

List值一

List值二

List值三

Set值二

Set值一

Set值三

first

second

third

注意:在相应的字段上一定要有setter 方法,才能注入。

补充:使用继承。在beans.xml中的配置如下:

相当于在XXX bean 实例中也有username 属性设置。

8.属性注入构造器方式

List值一

List值二

List值三

UserServiceBean对应的构造方法代码如下:

public UserServiceBean(String username, UserDao userDao, Set set) {

https://www.360docs.net/doc/78100657.html,ername=username;

https://www.360docs.net/doc/78100657.html,erDao=userDao;

this.set=set;

}

注意:此方法会覆盖掉默认的构造方法,导致要依赖默认构造方法的配置不可用,因此我们还应为此类提供一个默认的构造器。

三、使用注解方式注入

1.准备

注解方式的注入主要针对对象属性的注入。

使用注解功能要引用注解包,另beans.xml的配置模板如下:

xmlns:xsi="https://www.360docs.net/doc/78100657.html,/2001/XMLSchema-instance"

xmlns:context="https://www.360docs.net/doc/78100657.html,/schema/context"

xsi:schemaLocation="https://www.360docs.net/doc/78100657.html,/schema/beans

https://www.360docs.net/doc/78100657.html,/schema/beans/spring-beans-2.5.xsd

https://www.360docs.net/doc/78100657.html,/schema/context

https://www.360docs.net/doc/78100657.html,/schema/context/spring-context-2.5.xsd" >

2.Resource 注解实例

拷贝上一个项目为spring_02_annotation 项目,修改UserServiceBean 为如下形式:package com.asm.service;

public class UserServiceBean {

@Resource(name = "userDaoImpl")

private UserDao userDao;

private UserDao userDao2;

@Resource

public void setUserDao2(UserDao userDao2) {

https://www.360docs.net/doc/78100657.html,erDao2 = userDao2;

}

public void test() {

userDao.save();

userDao2.save();

}

}

然后在bean.xml 中的配置如下:

简要说明:Resouce注解可以在字段上标记,也可以在对应的setter方法上标记。此注解可以不使用name属性,它会自动去查找匹配的类型(先以字段名称为name的值查找,如找不到会再根据依赖对象的类型查找)。但只要使用了name属性,就应确保name的值在xml中有相应

的bean Id对应。它是属于java本身的注解,Resource默认按属性名称装配

3.Autowired注解实例

@Autowired(required=false)

@Qualifier("userDaoImplXXX")

private UserDao userDao3;

说明:Autowired 默认是按照类型来查找对应的bean 实例注入,如果想注入指定名称的bean 实例,可以使用Qualifier 注解来指定名字。Required 属性设为true 时,如果不能成功注入则会报告异常,如果为设为false 而不能成功注入,则会将userDao3 设为null。同样地,它也实用于setter 方法。它属于spring 特有的注解,Autowired 默认按类型装配。

4.自动装配

自动装配(了解,不建议使用):除了要设置字段的setter方法外,还应在beans.xml配置文

件中设置如下内容:

class="https://www.360docs.net/doc/78100657.html,erServiceBean2" autowire="byType"/>

说明:除了byType外,autowire的可选属性如下:

byName:根据类中的字段名来查找对应的bean,如不能成功注入,则字段设为null. byType:根据类型装配,如果发现多个类型都能够匹配,则抛出异常。

Consturctor:也byType相似,不同之处在于它应用于构造器的参数,如果容器中没有找到与构造器参数类型一致的bean,则抛出异常。

Autodetect:通过bean类的自省机制来决定是使用consturctor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。

四、自动扫描管理bean

1.准备工作

在前面使用注解的时候,除了结点配置增加了名称空间说明,另还增加了

配置,它的作用就是注册一个处理器。通常情况下,我

们要使用某个bean实例,总会配置相关内容。Spring最新版本可以简化这一操作,即是说我们只要在配置文件作如下设置:

便可以自动管理指定包名及子包

下标住了@service (业务层组件)、@controller(控制层组件)、@repository(数据访问

组件)或@component(泛指组件)的类,并把它们作一个实例bean,相当于在beans.xml中配置了元素。需要说明的是,使用了此配置同时意味着还注册了注解配置的处理器,所以在这些类中用到了注解配置时并不需要再配置

为什么提出自动扫描管理:在一些比较大的项目中,涉及到的bean实例会有很多,如果依次对每个bean实例进行配置,不但配置内容繁琐,而且配置文件也会显得杂乱。因此spring 提出了自动扫描bean,它依据在xml文件中指定的包名和类中标记的component系列注解。2.实例

建立spring_03_autoscan项目,内容基本和前面两个项目一样,只是在要纳入spring管理的类前增加了component这样的注解。Beans.xml的配置如下:

xmlns:xsi="https://www.360docs.net/doc/78100657.html,/2001/XMLSchema-instance"

xmlns:context="https://www.360docs.net/doc/78100657.html,/schema/context" xsi:schemaLocation="https://www.360docs.net/doc/78100657.html,/schema/beans https://www.360docs.net/doc/78100657.html,/schema/beans/spring-beans-2.5.xsd https://www.360docs.net/doc/78100657.html,/schema/context

https://www.360docs.net/doc/78100657.html,/schema/context/spring-context-2.5. xsd"

>

说明:以上的配置会自动管理service 包和impl 包及它们子包下的带有component 标记的类,上面两行配置代码等价于

下面以UserServiceBean 为例进行说明,代码如下:

package com.asm.service;

@Service("usb")@Scope("singleton")

public class UserServiceBean {

@Resource(name = "userDaoImpl")

private UserDao userDao;

private UserDao userDao2;

@Autowired(required = true)

@Qualifier("userDaoImpl")

private UserDao userDao3;

@Resource

public void setUserDao2(UserDao userDao2) {

https://www.360docs.net/doc/78100657.html,erDao2 = userDao2;

}

public UserServiceBean() {

}

@PostConstruct

public void init() {

System.out.println("init method is called");

}

public void test() {

System.out.println("********************************");

userDao.save();

userDao2.save();

System.out.println(userDao3);

// userDao3.save();

System.out.println("********************************");

}

}

说明:如果使用Service这些注解时不指定名称,这些实例bean的名称就是类名(但首字母

小写),也可以指定实例bean的名字,比如这里指定其名字为“usb”,scope注解配置了bean 的作用范围,PostConstruct注解指定了bean的init方法。关于其它的一些注解配置参文档(3.11-3.12)。

它的junit测试代码如下:

public class AutoScanTest {

@Test

public void base() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beans.xml");

UserServiceBean udb = (UserServiceBean) ctx.getBean("usb");

udb.test();

}

}

小结使用自动扫描管理的核心:配置扫描的包、类前的component标记、了解常用注解。

五、AOP 技术

1.引出问题

建立spring_04_aop项目,在该项目下有一个UserDao接口,代码如下:

package com.asm.dao;

public interface UserDao {

void save();

void update();

}

该接口的实现类UseDaoImp,代码如下:

package com.asm.dao.impl;

import https://www.360docs.net/doc/78100657.html,erDao;

public class UserDaoImp implements UserDao {

private String username;

public UserDaoImp() {

}

public UserDaoImp(String username) {

https://www.360docs.net/doc/78100657.html,ername = username;

}

public String getUsername() {

return username;

}

@Override

public void save() {

System.out.println("save method is called:" + username);

}

@Override

public void update() {

System.out.println("update method is called" + username);

}

}

需求如下:如果实现类的username!=null,才可以调用save 与update 方法,为null 则不能调用。当然要解决此问题,可以在save 与update 方法内部进行判断,但是如果在方法内部进行判断,代码则失去了灵活性,如果以后的需求改变,比如变成username.equals 时,则又要在update/save 方法中重新进行一次判断。如果save/update 这样的方法很多,这样就会很麻烦。其实要解决此问题,可以通过动态代理技术实现。这里的需求其实就是根据要求来拦截一些业务方法,这种编程问题称之为横切性关注点。

代理的目标对象必须实现了一个接口---横切关注点

2.动态代理实现[JDK]

建立代理工厂ProxyFactory,代码如下:

package com.asm.dao.impl.factory;

public class ProxyFactory implements InvocationHandler {

private Object target;

public Object createUserDaoImp(Object target) {

this.target = target;

return

Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

UserDaoImp udi = (UserDaoImp) target;

Object result = null;

if(udi.getUsername() != null) {

result = method.invoke(target, args);

}

return result;

}

}

简析动态代理:此类根据传递的target 对象来生成此目标对象的代理对象,需要强调的是动态代理技术所要代理的对象必须实现一个接口。newProxyInstance 参数说明:第一个

参数是目标对象的类装载器,第二个参数是目标对象的接口,第三个参数是回调对象,生成的代理对象要执行方法时就是依靠这个回调对象的invoke 方法来进行目标对象的方法回调。关于动态代理的其它细节不在此讨论。

建立junit 测试代码,内容如下:

public class AopProxyTest {

@Test //用户名为空,不执行方法

public void testProxy(){

ProxyFactory pf=new ProxyFactory();

UserDao ud=(UserDao) pf.createUserDaoImp(new UserDaoImp());

ud.save();

}

@Test //用户名为不为空,才执行save方法

public void testProxy2(){

ProxyFactory pf=new ProxyFactory();

UserDao ud=(UserDao) pf.createUserDaoImp(new UserDaoImp("张某")); ud.save();

}

}

3.cglib 实现代理

JDK的Proxy实现代理要求被代理的目标对象必须实现一个接口,而如果目标对象没有实现接口则不能使用Proxy来代理。其实也可以借助cglib来实现代理。操作步骤如下

步骤一、建立UserDaoImp2类,它与UserDaoImp的唯一区别就是没有实现任何接口。步骤二、导入cglib.jar包,创建cglib代理工厂,代码如下:

package com.asm.dao.impl.factory;

public class CglibFactory implements MethodInterceptor {

private Object target;

public Object createUserDaoImp2(Object target) {

this.target = target;

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(this.target.getClass());

// cglib创建的代理对象,其实就是继承了要代理的目标类,然后对目标类中所有非final 方

法进行覆盖,但在覆盖方法时会添加一些拦截代码。

enhancer.setCallback(this); //注册回调器

return enhancer.create();

}

@Override

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)

throws Throwable {

UserDaoImp2 udi = (UserDaoImp2) target;

Object result = null;

if(udi.getUsername() != null) {

// 前置通知

try{

result = methodProxy.invoke(target, args);

// 后置通知

} catch (Exception e) {

e.printStackTrace();

// 例外通知

} finally {

// 最终通知

}

}

return result;

}

}

说明:注意注释的通知,通知就是拦截到方法后执行的一些代码,比如前置通知,就是说在回调目标方法时执行的一些操作。

步骤三、建立测试代码(省略,和五.2 的测试代码相似)

4.aop 理论知识

横切性关注点:对哪些方法拦截,拦截后怎么处理,这些关注就称之为横切性关注点

切面(aspect):类是对物体特征的抽象,而切面是指对横切性关注点的抽象。

连接点(joinpoint):被拦截到的点,因为spring 只支持方法类型的连接点,所以在spring 中连接点指的就是被拦截到的方法。实际上连接点还可以是字段或构造器。

切入点(pointcut):对连接点进行拦截的定义。

通知(advice):所谓通知就是指拦截到连接点之后的要执行的代码。通知分为前置、后置、异常、最终。环绕通知五类。

目标对象:代理的目标对象。

织入(weave):将切面应用到目标对象并导致代理对象创建的过程

引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

5.基于spring 的AOP 实现

步骤一、导入spring 开发的基本包(包括切面及注解包)

步骤二、编写切面类TheInterceptor,代码如下:

package com.asm.dao.impl.factory;

@Aspect

public class TheInterceptor {

@Pointcut("execution (* https://www.360docs.net/doc/78100657.html,erDaoImp.*(..))")

// 声明一个切入点(第一个*后要留一个空格)

private void anyMethod() {

}

@Before("anyMethod()")// 前置通知

public void before() {

System.out.println("前置通知");

}

@AfterReturning("anyMethod()")//后置通知

public void afterReturning(){

System.out.println("后置通知");

}

}

简析:Aspect 注解声明此类为一个切面类,Pointcut 注解用来声明一个切入点,括号中的参数是切入点的表达式,这里的表达式的意思是对UserDaoImp 类的所有方法进行拦截。关于切入点表达式后面会有详细的说明。anyMethod 是为切入点起一个名字,后面的“通知”都要依赖这个名字。

步骤三、beans.xml 配置文件的内容如下:

xmlns:xsi="https://www.360docs.net/doc/78100657.html,/2001/XMLSchema-instance"

xmlns:context="https://www.360docs.net/doc/78100657.html,/schema/context"

xmlns:aop="https://www.360docs.net/doc/78100657.html,/schema/aop"

xsi:schemaLocation="https://www.360docs.net/doc/78100657.html,/schema/beans https://www.360docs.net/doc/78100657.html,/schema/beans/spring-beans-2.5.xsd https://www.360docs.net/doc/78100657.html,/schema/context

https://www.360docs.net/doc/78100657.html,/schema/context/spring-context-2.5. xsd

https://www.360docs.net/doc/78100657.html,/schema/aop

https://www.360docs.net/doc/78100657.html,/schema/aop/spring-aop-2.5.xsd">

class="com.asm.dao.impl.factory.TheInterceptor" />

说明:要想切面类起作用,首先要把切面类纳入spring容器管理。

步骤四、编写junit测试单元

@Test

public void base() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beans.xml");

// UserDaoImp udii=(UserDaoImp) ctx.getBean("userDaoImp");

UserDao ud = (UserDao) ctx.getBean("userDaoImp");

System.out.println(ud.getClass().getName());

ud.save();

}

说明:由于开启了切面编程功能,所以当我们获取一个被切面类监控管理的bean对象—UserDaoImp时,它实际上获取的是此对象的一个代理对象,而在spring中对代理对象的处

理有如下原则:(1)如果要代理的对象实现了接口,则会按照Proxy的方式来产生代理对象,

这即是说产生的代理对象只能是接口类型,比如起用上面注掉的代码就会报错,而且通过下面的

打印语句我们也可以看出产生的是一个代理对象。(2)要代理的对象未实现接口,则按cglib

方式来产生代理对象。另还要注意:要想spring的切面技术起作用,被管理的bean对象只能

是通过spring容器获取的对象。比如这里如果直接new出UseDaoImp对象,则new出的对象是

不能被spring的切面类监控管理。

补充:测试被代理对象未实现接口时,spring切面技术的应用。

步骤一、修改切面类TheInterceptor切入点为如下内容:

@Pointcut("execution (* com.asm.dao.impl.*.*(..))")

说明:拦截impl包下的所有类所有方法

步骤二、在beans.xml中增加如下内容:

步骤三、junit测试代码如下:

public void base2() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beans.xml");

UserDaoImp2 udi2 = (UserDaoImp2) ctx.getBean("userDaoImp2"); System.out.println(udi2.getClass().getName());

System.out.println(udi2.getClass().getSuperclass().getName());

udi2.save();

}

说明:UseDaoImp2 未实现任何接口,因此在spring 中利用切面技术来管理此类使用的动态

代理技术实质是cglib 的动态代理方式,所以产生的代理对象实质是被代理对象的一个子类,

通过上面的控制台打印语句可以看出。

小结:(1)声明aspect 的切面类要纳入spring 容器管理才能起作用。(2)被管理的bean

实例要通过容器的getBeans 方法获取。(3)依据被管理的bean 是否实现接口,spring 采取两种方式来产生代理对象。(4)在xml 文件中启用

6.通知应用实例(基于注解)

在前一节,我们应用了前置通知和后置通知,除了这两个通知外,下面接着演示其它通知的应用。

(1)最终通知

在切面类TheInterceptor中增加如下代码即可:略去测试。

@After("anyMethod()")// 最终通知

public void after() {

System.out.println("最终通知");

}

(2)异常通知

为了演示此实例,我们在UseDaoImp 中增加如下代码以抛出异常:

int i=1/0;在然后在切面类TheInterceptor中增加如下代码:

@AfterThrowing("anyMethod()") // 例外通知

public void AfterThrowing() {

System.out.println("例外通知");

}

当获取代理对象并调用save 方法时会抛出异常,例外通知便会得以执行。

(3)环绕通知

@Around("anyMethod()") //环绕通知

public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入环绕");

//if(){ // 进行一些判断,再执行环绕

Object result = pjp.proceed();

//}

System.out.println("退出环绕");

return result;

}

注意的是方法的参数及抛出异常类型的固定写法(方法名可以是任意得),另在该方法中必须执行pjp.proceed()才能让环绕通知中的两处打印代码得以执行。即是说要想环绕通知的拦截处理代码起作用必须调用pjp.proceed 方法。补充:环绕通知通常可以用来测试方法的执行时间,在pjp.proceed 前获取一个时间,在pjp.proceed 方法后再获取一个时间。最后两

个时间相减即可得方法执行时间。

(4)传递参数给通知

首先在UseDao接口中增加如下代码:

String add(String name);

然后再在UserDaoImp中实现此方法,代码如下:

public String add(String name) {

System.out.println("add method is called [ " + name+" ]");

return "添加成功";

}

需求:获取调用add方法传递的参数。操作步骤如下:在切面类增加如下代码:

@Before("anyMethod() && args(name)")// 前置通知,只针对UseDaoImp的add 方法

public void beforeAdd(String name) {

System.out.println("前置通知:" + name);

}

说明:在前置通知的方法中有一个参数,然后再把此参数作为拦截条件(即是说拦截带有一个

String类型参数的方法)。args的名字和beforeAdd方法参数名字相同。

测试代码:

public void advieeTest() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beans.xml");

UserDao ud=(UserDao) ctx.getBean("userDaoImp");

ud.add("xxx");

}

(5)获取方法的返回值

我们知道add方法有一个返回值,我们对此方法进行拦截并获取返回值,在切面类中增加如下代码:

@AfterReturning(pointcut = "anyMethod()", returning = "result")

// 后置通知,监听返回结果,针对UserDaoImp的getUsername()方法

public void afterReturningRes(String result) {

System.out.println("后置通知,返回结果:" + result);

}

说明:afterReturningRes 方法的参数就是要返回的参数类型,returning 标记的就是的

结果,它的取值与该方法参数名相同。测试代码同(4)。

(6)获取抛出的异常

切面类的增加如下代码:

@AfterThrowing(pointcut="anyMethod",throwing="e")

public void catchException(Exception e){

System.out.println("获取抛出的异常:"+e);

}

throwing 的取值和方法的参数名相同,测试代码省略。

7. 通知应用实例(基于XML)

步骤一、复制TheInterceptorX 类为TheInterceptorXML,并去掉所有注解。

步骤二、建立beansXML.xml配置文件,内容如下:

class="com.asm.dao.impl.factory.TheInterceptorXML" />

--声明一个切面类

expression="execution(* https://www.360docs.net/doc/78100657.html,erDaoImp.*(..))" />

method="afterReturningRes" returning="result" />

method="catchException" throwing="e"/>

测试代码如下:

public void advieeTest() {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("beansXML.xml");

UserDao ud=(UserDao) ctx.getBean("userDaoImp");

ud.add("xxx");

}

未解决问题:不能成功传参给前置通知。

8.解析切入点表达式

1.格式:execution(返回值空格方法选择)。两部分组成,中间一定要有空格。

返回值:可以是*,说明拦截任何方法。https://www.360docs.net/doc/78100657.html,ng.String(全名),拦截返回值为String 类型的方法。常用的实例如下:

方法选择:包名[类名].*()。设定要拦截的方法签名。

表达式(省略execution)说明

(https://www.360docs.net/doc/78100657.html,ng.String 方法选择略) 拦截返回值为String 类型的方法

(!void方法选择略) 拦截返回值非空的方法

(* com.asm..*.*(..)) 拦截com.asm 包及子包下每个类的全部方法

(* com.asm.*.*(..)) 拦截com.asm 包下每个类的全部方法

(* https://www.360docs.net/doc/78100657.html,er.*(..)) 拦截asm 包下User 类的所有方法

(* https://www.360docs.net/doc/78100657.html,er.*

(https://www.360docs.net/doc/78100657.html,ng.String,..))

拦截User 类中第一个参数为String,后面参

数任一的方法

待增加

待增加

9.总结

面向切面的常见应用(如权限拦截)、spring 的aop 依赖两种方式实现代理(依被代理的对

象是否实现接口而定)、通知概念、基于注解与基于XML 两种方式来配置切面、基本步骤(依要拦截的方法来设定切入点,依据业务需求实现拦截通知代码,切面纳入spring 容器管理,要被监控的类只能是通过Spring 容器获取)、切入点的格式。

六、与JDBC 集成

1.搭建环境

建立spring_05_integrationJdbc 项目,此项目使用dbcp 作为数据源来整合JDBC 技术。因此除了spring 所需的jar 包,还应导入dbcp 的jar 包:commons-dbcp-1.2.2.jar 及此jar

所依赖的两个apache 开源jar 包:commons-collections-3.1.jar、commons-pool.jar。由于涉及到数据库操作,还应导入数据库驱动包,这里选择的是mySQL 驱动。

2.基于注解的事务管理

步骤一、配置事务管理器。

建立beans.xml文件,它的内容如下:

xmlns:xsi="https://www.360docs.net/doc/78100657.html,/2001/XMLSchema-instance"

xmlns:aop="https://www.360docs.net/doc/78100657.html,/schema/aop"

xmlns:tx="https://www.360docs.net/doc/78100657.html,/schema/tx"

xmlns:context="https://www.360docs.net/doc/78100657.html,/schema/context"

xsi:schemaLocation="

https://www.360docs.net/doc/78100657.html,/schema/beans

https://www.360docs.net/doc/78100657.html,/schema/beans/spring-beans-2.5.xsd https://www.360docs.net/doc/78100657.html,/schema/tx

https://www.360docs.net/doc/78100657.html,/schema/tx/spring-tx-2.5.xsd

https://www.360docs.net/doc/78100657.html,/schema/aop

https://www.360docs.net/doc/78100657.html,/schema/aop/spring-aop-2.5.xsd

https://www.360docs.net/doc/78100657.html,/schema/context

https://www.360docs.net/doc/78100657.html,/schema/context/spring-context-2.5. xsd"

>

class="https://www.360docs.net/doc/78100657.html,mons.dbcp.BasicDataSource">

class="org.springframework.jdbc.datasource.DataSourceTransactionM anager">

说明:首先是配置了一个数据源,以供数据源事务管理器配置引用。接着配置了数据源事务管

理器,随后开启了基于@Transactional注解的事务管理器,开启后,只要是被spring 管理的

bean且打有@Transactional注解的bean都会受配置的事务管理。关于这里的配置可参看

spring文档9.5.6

步骤二、准备使用环境。

建立UserDao接口,代码如下:

package com.asm.dao;

public interface UserDao {

void save(User user);

void delete(User user);

void update(User user);

User get(int id);

ListgetUsers();

}

建立UserDaoImp类实现UseDao接口,代码如下:

package com.asm.dao.impl;

@Transactional

public class UserDaoImp implements UserDao {

private JdbcTemplate jdbcTemplate;

public void setDatasouce(DataSource datasource) {

jdbcTemplate= new JdbcTemplate(datasource);

}

public void delete(User user) {

jdbcTemplate.update("delete from user where id=?", new Object[] { user.getId() },

new int[] { java.sql.Types.INTEGER });

}

public User get(int id) {

return(User) jdbcTemplate.queryForObject("select * from user

where id=?",

new Object[] { id }, new int[] { java.sql.Types.INTEGER },

new RowMapper() {

public Object mapRow(ResultSet rs, int arg1) throws

SQLException {

User user = new User();

user.setId(rs.getInt("id"));

user.setName(rs.getString("name"));

return user;

}

});

}

@SuppressWarnings("unchecked")

public List getUsers() {

return(List) jdbcTemplate.query("select * from user", new RowMapper() {

public Object mapRow(ResultSet rs, int arg1) throws

SQLException {

User user = new User();

user.setId(rs.getInt("id"));

user.setName(rs.getString("name"));

return user;

}

});

}

public void save(User user) {

jdbcTemplate.update("insert into user(name) values(?)", new

Object[] { user.getName() },

new int[] { java.sql.Types.VARCHAR });

}

public void update(User user) {

jdbcTemplate.update("update user set name=? where id=?", new Object[] { user.getName(),

user.getId() }, new int[] { java.sql.Types.VARCHAR,

java.sql.Types.INTEGER });

}

}

步骤三、把UserDaoImp纳入spring容器管理。

在beans.xml中增加对应的配置内容如下:

结合配置文件解析UserDaoImp实现类:(1)此类作为一个bean实例纳入spring容器管理,使用setter注入方式完成对datasource的注入,实质是完成的JdbcTemplate对象的初始

化。(2)该类CRUD方法都使用了Spring容器提供的JdbcTemplate对象来简化了CRUD操作,在spring文档的11.2.1.节对JdbcTemplate类作了较详细的介绍。(3)此类打上了

@Transactional注解,表示此类中的业务方法都会受beans.xml配置的

管理

步骤四、编写测试类

package com.asm.test;

public class TestSJ {

private UserDao ud = (UserDao) new

ClassPathXmlApplicationContext("beans.xml").getBean("userDaoImp") ;

public static void main(String[] args) {

TestSJ sj = new TestSJ();

sj.save();

sj.delete();

}

public void save() {

User user = new User();

user.setName("张某某");

ud.save(user);

}

public void delete() {

User user = new User();

user.setId(1);

ud.delete(user);

}

//其它测试方法省略...

}

说明:注意这里通过getBean获取的是UserDao接口对象,而非UserDao接口的实现类UserDaoImp对象,因为spring的事务管理也是利用了aop技术,所以必须要面向接口,如果

想通过getBean获取它的实现类对象将会报错。

步骤五、感知事务管理。

在UserDaoImp的delete方法中增加如下代码:

jdbcTemplate.update("delete from user where id=?", new Object[] { user.getId() }, new int[] { java.sql.Types.INTEGER });

int i=5/0;

jdbcTemplate.update("delete from user where id=2");

s pring 默认的事务管理方式:运行期异常进行事务回滚,非运行期异常不进行事务回滚。因此增加上面的代码后,会出现ArithmeticException 运行期异常。所以当出现此异常时,delete 方法中的数据库操作都会进行回滚,因而id=1 和2 这两条记录都不会被删除。如果把UseDaoImp 类前标记@Transactional 的注解去掉,id=1 的记录会被删除,因为失去

了spring 容器的事务管理。

小结spring 事务:

(1)在beans.xml 中配置事务管理器,可以是依赖于数据源的事务管理器,也可以其它的事务管理器(比如和JPA 集成的事务管理器等),这些事务管理器类都继承自AbstractPlatformTransactionManager 抽象类。(2)事务管理器配置后,要想让配置的事务管理器对某些类的事务管理起作用,可以有两种方式配置:一种是声明式配置(两种:基于注解或基于XML),一种是编程是配置。(3)上面的一些操作,都是基于注解的声明式事务配置:关键两点:开启基于事务的注解支持();被管理的类打上事务注解标记。(4)除了

可以在类前声明事务标记,也可以在类的方法中具体声明详细的事务标记。(5)事务标记具有多个可选属性,具体可参文档9.5.6.1。

3.简析事务注解属性

@Transactional 注解具有大属性:

(1)传播属性propagation:

可选属性说明

REQUIRED 业务方法需要在一个事务中运行,如果方法运行时,已经处在一个事务中,

那么加入到该事务,否则自己创建一个新的事务。

REQUIRESNEW 不管是否存在事务,业务方法总会为自己发起一个新的事务,如果方法已

经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方

法执行结束,新事务才算结束,原先的事务才恢复执行。

SUPPORTS 如果业务方法在某个事务范围内被调用,则业务方法成为该事务的一部分。

如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行

NOT_SUPPORTED 声明业务方法不需要事务,如果方法没有关联到一个事务,容器不会为它开启事务,如果方法在一个事务中被调用,则该事务会被挂起,在该方法

调用结束后,原先的事务恢复执行

NEVER 指定业务方法绝对不能在事务范围中执行,如果业务方法在某个事务中执

行,容器会抛出例外;只有业务方法没有关联到任何事务,才能正常执行。MANDATORY 指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己

的事务。如果业务方法在没有事务的环境下调用,容器就会抛出例外

NESTED 如果一个活动的事务存在,它会自己产生一个单独的而且拥有多个可以回

滚的保存点的事务,然后嵌套运行在活动的事务中,实质它可以看成是一

个内部事务且具有回滚保存点,所以内部自身的事务回滚并不会引起外部

活动事务的回滚,它只是回滚到内部事务的保存点。如果没有活动事务,

则按REQIIRED 属性执行。需要注意的是此配置只对

DataSourceTransactionManager 事务管理器生效。

说明:上面多次提到业务方法,它实质就是UserDaoImp 中save 等这样的方法。但是这些方法前会有一个设定了详细属性的@Transactional 注解。比如:

@Transactional(propagation="",isolation="",noRollbackFor="") (2)隔离级别属性isolation:这个是依赖数据库系统而言,数据库系统提供四种事务隔离级别。(具体的事务隔离级别分析在些略过,可以参看网络资源及相关文档)

(3)只读属性readOnly:false--读写性、true--只读性事务.

(4)超时属性timeout:int 型,以秒为单位。

(5)回滚属性:根据抛出的异常决定是否回滚事务,它包括四种可选属性。参文档9.5.6.1 的表9.3

4.扩展:抽取dpcp 配置文件。

多图详解Spring框架的设计理念与设计模式

Spring作为现在最优秀的框架之一,已被广泛的使用,51CTO也曾经针对Spring框架中的JDBC应用做过报道。本文将从另外一个视角试图剖析出Spring框架的作者设计Spring框架的骨骼架构的设计理念。 Rod Johson在2002年编著的《Expert one to one J2EE design and development》一书中,对Java EE正统框架臃肿、低效、脱离现实的种种现状提出了质疑,并积极寻求探索革新之道。以此书为指导思想,他编写了interface21框架,这是一个力图冲破Java EE传统开发的困境,从实际需求出发,着眼于轻便、灵巧,易于开发、测试和部署的轻量级开发框架。Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。同年他又推出了一部堪称经典的力作《Expert one-to-one J2EE Development without EJB》,该书在Java世界掀起了轩然大波,不断改变着Java开发者程序设计和开发的思考方式。在该书中,作者根据自己多年丰富的实践经验,对EJB 的各种笨重臃肿的结构进行了逐一的分析和否定,并分别以简洁实用的方式替换之。至此一战功成,Rod Johnson 成为一个改变Java世界的大师级人物。 传统J2EE应用的开发效率低,应用服务器厂商对各种技术的支持并没有真正统一,导致J2EE的应用没有真正实现Write Once及Run Anywhere的承诺。Spring作为开源的中间件,独立于各种应用服务器,甚至无须应用服务器的支持,也能提供应用服务器的功能,如声明式事务等。 Spring致力于J2EE应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。然而,Spring并不想取代那些已有的框架,而与它们无缝地整合。 Spring简介 Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring 使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 ◆目的:解决企业应用开发的复杂性 ◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能 ◆范围:任何Java应用 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 ◆轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且 Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。 ◆控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。 ◆面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务()管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。 ◆容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。 ◆框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将

Spring技术内幕:深入解析Spring架构与设计原理

---------------------------------------------------------------最新资料推荐------------------------------------------------------ Spring技术内幕:深入解析Spring架构与设计原 理 Spring 技术内幕: 深入解析 Spring 架构与设计原理 Spring 技术内幕深入解析 Spring 架构与设计原理(一)引子缘起已经很久没有写帖子了,现在总算是有点时间写些东西,也算是对自己的一个记录吧。 刚刚完成了一个软件产品,从概念到运营都弄了一下,正在推广当中,虽然还没有能够达到盈亏平衡,但是这个过程,对自己也算是一种历练。 先不管结果如何,好呆走过这么一遭了。 我打算用这个帖子,把自己在这个过程中的一些心得,特别是对 Spring 新的理解,记录下来。 使用这个帖子的标题,持续下来。 简单来说,自己的软件产品是一个基于互联网的 SaaS 协同软件平台, 操作简单,支持流程定义,管理和多种客户端 -像短信, MSN,智能手机什么的(我这里就不多做什么广告了),也有一个企业版的版本,使用的技术框架是 Hibernate + Spring + Wicket,下面是 Linux 和 MySQL,还有云计算的平台的使用,以支持其扩展性,虽然现在还没有可扩展性的需求,但似乎不难从SaaS 上,就会想到云计算, 其实,它们真的是天生的一对! 1 / 3

关于云计算,自己对这个技术很感兴趣,觉得和开源软件的结合,是很有意思的,因为它们都有基于服务的基因,在云计算平台的使用上,也有一些初步的实践。 云计算是一个很有意思的话题,但在这里主要是想谈 Spring,所以对云计算,这里就先不多说了,但非常欢迎有兴趣的朋友和一起另外找地方讨论!回到正题,在我自己的产品中,其中除了Wicket 和云计算外,其他都是大家非常熟知的了,像Hibernate, Spring, MySQL 什么的。 在这个过程中,发现自己对一些技术点也有了新的认识,最有体会的是 Spring。 当然,在这个过程中,更大的收获是对产品开发整个过程的认识,在这点上,真是一言难尽. . . . . . . . 回到自己还算了解的 Spring, 这次我使用的是 3. 0 的代码,所以,有机会也把这些代码读了几遍,比原来的理解要加深了许多,也发现了不少和 2. 0 代码不同的地方,以及自己一些对 Spring 的新的理解,这些,就让我就用这个帖子系列,给自己总结一下,也算是对自己以前的那个代码分析的帖子做一个新的交代吧。 自己对 Spring 一点小小的见解简化 Java 企业应用的开发,是Spring 框架的目标. 就是我们熟知的当年的那个interface21,也亦非吴下阿蒙了,由它演进出来的 Spring,以及由它带来的崭新开发理念,也早已伴随着这个开源框架的广泛应用,而飞入寻常百姓家。

java框架Spring2复习题

一、选择题(每题2分,共计100分) 1.下面关于AOP的说法错误的是()。 A.AOP将散落在系统中的“方面”代码集中实现 B.AOP有助于提高系统的可维护性 C.AOP已经表现出了将要替代面向对象的趋势 D.AOP是一种设计模式,Spring提供了一种实现 2.事务隔离级别是由谁实现的?()。 A.Java应用程序 B.Hibernate C.数据库系统 D.JDBC驱动程序 标准SQL规范: 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别;为了解决更新丢失,脏读,不可重读(包括虚读和幻读)等问题在标准SQL规范中,定义了4个事务隔离级别,分别为未授权读取,也称为读未提交(read uncommitted);授权读取,也称为读提交(read committed);可重复读取(repeatable read);序列化(serializable). 3.下列哪项不是Spring的依赖注入方式()。[选两项] A.setter注入 B.getter注入 C.接口注入 D.构造注入 4.在Spring框架中,面向方面编程(AOP)的目标在于( )。 A.编写程序时不用关心其依赖组件的实现 B.将程序中涉及的公用问题集中解决 C.封装JDBC访训数据库的代码,简化数据访训层的得复性代码 D.实现面面的”无刷新”

A.Spring提供了HibernateDaoSupport类来简化Hibernate的使用 B.在Spring配置文件种可以通过Spring提供的LocalSessionFactoryBean,来获得SessionFactory的实例 C.通过集成Spring和Hibernate,用Spring管理程序的依赖关系,将SessionFactory 注入到DataSource中 D.通过Spring,可以在Biz层代码中无需直接实例化DAO类,而是通过注入得到 6.依赖注入说法正确的是()。 A.依赖注入的目标是在代码之外管理程序组建间的依赖关系 B.依赖注入即是“面向接口”的编程 C.依赖注入是面向对象技术的替代品 D.依赖注入的使用会增大程序的规模 7.关于spring说法错误的是()。 A.spring是一个轻量级JAVA EE的框架集合 B.spring是“依赖注入”模式的实现 C.使用spring可以实现声明事务 D.spring提供了AOP方式的日志系统8.在Spring 中,配置Hibernate 事务管理器(Hibernate TransactionManager)时,需要 注入的属性名称是( )。 A.dataSource B.sessionFactory C.baseHibernateDao D.transactionProxyFactoryBean 9.下面()不是Spring AOP中的通知类型。 A.前置通知 B.后置通知 C.代理通知 D.异常通知

各技术框架架构图

各种系统架构图及其简介 1.Spring 架构图 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为J2EE 应用程序开发提供集成的框架。Spring 框架的功能可以用在任何J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定J2EE 服务的可重用业务和数据访问对象。这样的对象可以在不同J2EE 环境(Web或EJB )、独立应用程序、测试环境之间重用。 组成Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下: ?核心容器:核心容器提供Spring 框架的基本功能。核心容器的主要组件是BeanFactory ,它是工厂模式的实现。BeanFactory 使用控制反转(IOC )模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。 ?Spring 上下文:Spring 上下文是一个配置文件,向Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如JNDI 、EJB 、电子邮件、国际化、校验和调度功能。 ?Spring AOP :通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了Spring 框架中。所以,可以很容易地使Spring 框架管理的任何对象支持AOP 。Spring AOP 模块为基于Spring 的应用程序中的对象提供了事务管理服务。通过使用Spring AOP ,不用依赖EJB 组件,就可以将声明性事务管理集成到应用程序中。 ?Spring DAO :JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向JDBC 的异常遵从通用的DAO 异常层次结构。 ?Spring ORM :Spring 框架插入了若干个ORM 框架,从而提供了ORM 的对象关系工具,其中包括JDO 、Hibernate 和iBatis SQL Map 。所有这些都遵从Spring 的通用事务和DAO 异常层次结构。

Spring技术内幕:深入解析Spring架构与设计原理

Spring技术内幕 深入解析Spring架构与设计原理(一)引子 缘起 已经很久没有写帖子了,现在总算是有点时间写些东西,也算是对自己的一个记录吧。刚刚完成了一个软件产品,从概念到运营都弄了一下,正在推广当中,虽然还没有能够达到盈亏平衡,但是这个过程,对自己也算是一种历练。先不管结果如何,好呆走过这么一遭了。 我打算用这个帖子,把自己在这个过程中的一些心得,特别是对Spring新的理解,记录下来。使用这个帖子的标题,持续下来。 简单来说,自己的软件产品是一个基于互联网的SaaS协同软件平台,操作简单,支持流程定义,管理和多种客户端 -像短信,MSN,智能手机什么的(我这里就不多做什么广告了),也有一个企业版的版本,使用的技术框架是Hibernate + Spring + Wicket,下面是Linux和MySQL,还有云计算的平台的使用,以支持 其扩展性,虽然现在还没有可扩展性的需求,但似乎不难从SaaS上,就会想到云计算, 其实,它们真的是天生的一对! 关于云计算,自己对这个技术很感兴趣,觉得和开源软件的结合,是很有意思的,因为它们都有基于服务的基因,在云计算平台的使用上,也有一些初步的实践。云计算是一个很有意思的话题,但在这里主要是想谈Spring,所以对云计算, 这里就先不多说了,但非常欢迎有兴趣的朋友和一起另外找地方讨论! 回到正题,在我自己的产品中,其中除了Wicket和云计算外,其他都是大家非常熟知的了,像Hibernate, Spring, MySQL什么的。在这个过程中,发现自己对一些技术点也有了新的认识,最有体会的是Spring。当然,在这个过程中, 更大的收获是对产品开发整个过程的认识,在这点上,真是一言难尽........ 回到自己还算了解的Spring, 这次我使用的是3.0的代码,所以,有机会也把 这些代码读了几遍,比原来的理解要加深了许多,也发现了不少和2.0代码不同的地方,以及自己一些对 Spring的新的理解,这些,就让我就用这个帖子系列,给自己总结一下,也算是对自己以前的那个代码分析的帖子做一个新的交代吧。 自己对Spring一点小小的见解 简化Java企业应用的开发,是Spring框架的目标.就是我们熟知的当年的那个interface21,也亦非吴下阿蒙了,由它演进出来的 Spring,以及由它带来的崭新开发理念,也早已伴随着这个开源框架的广泛应用,而飞入寻常百姓家。与此同时,伴随着Spring的成熟,开源社区的成长,在Rod.Johnson的领导下,以

各种框架架构图简介

1.Spring 架构图 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为J2EE 应用程序开发提供集成的框架。Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定J2EE 服务的可重用业务和数据访问对象。这样的对象可以在不同J2EE 环境(Web或EJB )、独立应用程序、测试环境之间重用。 组成Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下: ?核心容器:核心容器提供Spring 框架的基本功能。核心容器的主要组件是BeanFactory ,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC )模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。 ?Spring 上下文:Spring 上下文是一个配置文件,向Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如JNDI 、EJB 、电子邮件、国际化、校验和调度功能。 ?Spring AOP :通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了Spring 框架中。所以,可以很容易地使Spring 框架管理的任何对象支持AOP 。Spring AOP 模块为基于Spring 的应用程序 中的对象提供了事务管理服务。通过使用Spring AOP ,不用依赖EJB 组 件,就可以将声明性事务管理集成到应用程序中。

?Spring DAO :JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向JDBC 的异常遵从通用的DAO 异常层次结构。 ?Spring ORM :Spring 框架插入了若干个ORM 框架,从而提供了ORM 的对象关系工具,其中包括JDO 、Hibernate 和iBatis SQL Map 。所有这些都遵从Spring 的通用事务和DAO 异常层次结构。 2.ibatis 架构图 ibatis 是一个基于Java的持久层框架。 iBATIS 提供的持久层框架包括SQL Maps 和Data Access Objects ( DAO ),同时还提供一个利用这个框架开发的 JPetStore 实例。 IBATIS :最大的优点是可以有效的控制sql 发送的数目,提高数据层的执行效率!它需要程序员自己去写sql 语句,不象hibernate 那样是完全面向对象的,自动化的,ibatis 是半自动化的,通过表和对象的映射以及手工书写的sql 语句,能够实现比hibernate 等更高的查询效率。 Ibatis 只是封装了数据访问层,替我们做了部分的对象关系映射。但代价是必须要写xml配置文件,相对于Hibernate 还要写很多sql 。Hibernate 通过工具直接从数据库模式生成实体类和基本的配置文件,而且大部分情况下不需要我们写sql ,会较大的提升开发效率。但这些也有很多的局限性,尤其是对

Spring教程

Spring教程

Spring教程 (1) Spring框架概述 (3) Spring是什么? (3) Spring的历史 (4) Spring的使命(Mission Statement) (4) Spring受到的批判 (4) Spring包含的模块 (4) 总结 (6) Spring的IoC容器 (6) 用户注册的例子 (7) 面向接口编程 (8) (用户持久化类)重构第一步——面向接口编程 (8) 重构第二步——工厂(Factory)模式 (9) 重构第三步——工厂(Factory)模式的改进 (10) 重构第四步-IoC容器 (10) 控制反转(IoC)/依赖注入(DI) (11) 什么是控制反转/依赖注入? (11) 依赖注入的三种实现形式 (12) BeanFactory (14) BeanFactory管理Bean(组件)的生命周期 (14) Bean的定义 (15) Bean的之前初始化 (18) Bean的准备就绪(Ready)状态 (21) Bean的销毁 (21) ApplicationContext (21) Spring的AOP框架 (21) Spring的数据层访问 (21) Spring的声明式事务 (21) Spring对其它企业应用支持 (21) 名词解释 容器: 框架: 组件: 服务:

Spring框架概述 主要内容:介绍Spring的历史,Spring的概论和它的体系结构,重点阐述它在J2EE中扮演的角色。 目的:让学员全面的了解Spring框架,知道Spring框架所提供的功能,并能将Spring 框架和其它框架(WebWork/Struts、hibernate)区分开来。 Spring是什么? Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring 的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 ?目的:解决企业应用开发的复杂性 ?功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能 ?范围:任何Java应用 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 ■轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。 ■控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。 ■面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务()管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。 ■容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean 可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。 ■框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。 所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它

Spring框架有哪几部分组成-

Spring框架有哪几部分组成? 问题:Spring框架有哪几部分组成? 回答: Spring框架有七个模块组成组成,这7个模块(或组件)均可以单独存在,也可以与其它一个或多个模块联合使用,主要功能表现如下: Spring 核心容器(Core):提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,她是工厂模式的实现。BeanFactory使用控制反转(Ioc)模式将应用程序的配置和依赖性规范与实际的应用代码程序分开。 Spring AOP:通过配置管理特性,Spring AOP模块直接面向方面的编程功能集成到了Spring框架中,所以可以很容易的使Spring框架管理的任何对象支持AOP。Spring AOP模块为基于Spring的应用程序中的对象提供了事务管理服务。通过使用Spring AOP,不用依赖于EJB组件,就可以将声明性事务管理集成到应用程序中。 Spring ORM:Spring框架集成了若干ORM框架,从而提供了ORM的对象关系工具,其中包括JDO、Hibernate、iBatis和TopLink。所有这些都遵从Spring的通用事务和DAO异常层结构。 Spring DAO:JDBC DAO抽象层提供了有意义的异常层次的结构,可用该结构来管理异常处理和不同数据供应商抛出的异常错误

信息。异常层次结构简化了错误处理,并且大大的降低了需要编写的异常代码数量(例如,打开和关系连接)。Spring DAO的面向JDBC 的异常遵从通用的DAO异常层结构。 Spring WEB:Web上下文模块建立在上下文模块(Context)的基础之上,为基于Web服务的应用程序提供了上下文的服务。所以Spring框架支持Jakarta Struts的集成。Web模块还简化了处理多部分请求及将请求参数绑定到域对象的工作。 Spring上下文(Context):Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,例如JNDI、EJB、电子邮件、国际化校验和调度功能。 Spring MVC:Spring的MVC框架是一个全功能的构建Web 应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的,MVC容纳的大量视图技术,包括JSP、Velocity、Tiles、iText 和Pol

Spring框架配置文件的编写

实验2 IoC——Bean的创建、Bean的生命周期、字面值和 对象类型属性的注入 一、实验目的 1. 掌握Bean的实例化方法 2. 掌握基于配置文件的属性注入方法 3. 掌握基于注解的属性注入方法 二、实验器材 1. 计算机 三、实验内容 1. 建立Boss类和Car类 2. 使用XML配置文件方式创建Bean并注入属性 3. 使用注解方式创建Bean并注入属性 四、实验步骤 第一步:建立Boss.java和Car.java 第二步:使用XML配置文件的方式创建Bean并注入属性

factory-bean="instanceFactory" factory-method="createCar"> 第三步:使用注解的方式创建Bean并且注入属性 Boss.java Car.java 五、实验报告要求 1. 写出详细实现步骤

Spring框架百科

spring框架 目录 定义文档来自于网络搜索 Spring框架简介文档来自于网络搜索 Spring框架的7个模块文档来自于网络搜索 编辑本段定义文档来自于网络搜索 要谈Spring的历史,就要先谈J2EE。J2EE应用程序的广泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核心中间层概念的标准化,但是在实践中并没有获得绝对的成功,因为开发效率,开发难度和实际的性能都令人失望。文档来自于网络搜索 曾经使用过EJB开发J2EE应用的人,一定知道,在EJB开始的学习和应用非常的艰苦,很多东西都不能一下子就很容易的理解。EJB要严格地继承各种不同类型的接口,类似的或者重复的代码大量存在。而配置也是复杂和单调,同样使用JNDI进行对象查找的代码也是单调而枯燥。虽然有一些开发工作随着xdoclet的出现,而有所缓解,但是学习EJB的高昂代价,和极低的开发效率,极高的资源消耗,都造成了EJB的使用困难。而Spring 出现的初衷就是为了解决类似的这些问题。文档来自于网络搜索 Spring的一个最大的目的就是使J2EE开发更加容易。同时,Spring 之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Old Java Object)对象提供企业级的服务。文档来自于网络搜索 Spring的形成,最初来自Rod Jahnson所著的一本很有影响力的书籍《Expert One-on-One J2EE Design and Development》,就是在这本书中第一次出现了Spring的一些核心思想,该书出版于2002年。另外一本书《Expert One-on-One J2EE Development without EJB》,更进一步阐述了在不使用EJB开发J2EE企业级应用的一些设计思想和具体的做法。有时间了可以详细的研读一下。文档来自于网络搜索 Spring的初衷: 1、J2EE开始应该更加简单。 2、使用接口而不是使用类,是更好的编程习惯。Spring将使用接口的复杂度几乎降低到了零。 3、为JavaBean提供了一个更好的应用配置框架。

spring框架学习笔记(全)

spring 1.这个框架并不像hibernate或struts那样为了完成特定的 功能(操作数据库、处理Http请求),它只是用来优化我们的工程的结果、提升设计、降低耦合度。 2.核心: 应用上下文ApplicationContext它就是用来管理工程 中无数类型的核心,一般通过xml文件或者注解来管理。它在启动时载入xml文件或注解中的类、类之间关系的信息,在使用时通过一些方式将管理的类型或对象取出使用。 3.(下载spring.zip,这里面包含了相应的jar包,以及文档) 第一个spring的应用: 1、导入jar包到工程中 2、在src下创建一个叫applicationContext.xml的配置文件 比如通过上述方式,我们就通过配置文件将,两个类Hello和Bye分别注册管理,其代号分别为hello和bye。

通过这两个代号,我们之后就能取出这个两个类的实例,并进行使用。(相应的类要Hello,Bye事先自己定义好) 3、使用ClassPathXmlApplicationContext来加载上一 步中的xml文件,以及获取其中的某个bean ApplicationContextctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 加载xml文件中的配置信息,两个类就被spring管理起来了Hello h = (Hello)ctx.getBean("hello"); 注意:取出bean时可以用多态 4.开闭原则: 对扩展开放,对修改关闭 需求变更时,尽量扩展一个类,不要去修改原来的类; 这样可以避免在原来正确的类上产生新的bug。 5.spring不但可以动态创建类的实例,也可以通过配置文件动态初始化实例的属性值 1、私有属性要有对应的setter方法 2、在bean中定义property属性,对应类中私有属性, *可以通过配置进行属性的自动设置。 在猫的bean中注册name属性,值为TOM

Spring 的骨骼架构

Spring 的骨骼架构 Spring 总共有十几个组件,但是真正核心的组件只有几个,下面是 Spring 框架的总体架构图: 图 1 .Spring 框架的总体架构图 从上图中可以看出 Spring 框架中的核心组件只有三个:Core、Context 和Beans。它们构建起了整个 Spring 的骨骼架构。没有它们就不可能有 AOP、Web 等上层的特性功能。下面也将主要从这三个组件入手分析 Spring。 Spring 的设计理念 前面介绍了 Spring 的三个核心组件,如果再在它们三个中选出核心的话,那就非 Beans 组件莫属了,为何这样说,其实 Spring 就是面向 Bean 的编程(BOP,Bean Oriented Programming),Bean 在 Spring 中才是真正的主角。 Bean 在 Spring 中作用就像 Object 对 OOP 的意义一样,没有对象的概念就像没有面向对象编程,Spring 中没有 Bean 也就没有 Spring 存在的意义。就像一次演出舞台都准备好了但是却没有演员一样。为什么要 Bean 这种角色 Bean 或者为何在 Spring 如此重要,这由 Spring 框架的设计目标决定,Spring 为何如此流行,我们用 Spring 的原因是什么,想想你会发现原来 Spring 解决了一个非常关键的问题他可以让你把对象之间的依赖关系转而用配置文件来管理,也就是他的依赖注入机制。而这个注入关系在一个叫 Ioc 容器中管理,那 Ioc 容器中有又是什么就是被 Bean 包裹的对象。Spring 正是通过把对象包装在Bean 中而达到对这些对象管理以及一些列额外操作的目的。

Spring框架有哪几部分组成

* Spring框架有哪几部分组成? Spring框架有七个模块组成组成,这7个模块(或组件)均可以单独存在,也可以与其它一个或多个模块联合使用,主要功能表现如下: ? Spring 核心容器(Core):提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,她是工厂模式的实现。BeanFactory 使用控制反转(Ioc)模式将应用程序的配置和依赖性规范与实际的应用代码程序分开。 ? Spring AOP:通过配置管理特性,Spring AOP模块直接面向方面的编程功能集成到了Spring框架中,所以可以很容易的使Spring 框架管理的任何对象支持 AOP。Spring AOP模块为基于Spring的应用程序中的对象提供了事务管理服务。通过使用Spring AOP,不用依赖于EJB组件,就可以将声明性事务管理集成到应用程序中。 ? Spring ORM:Spring框架集成了若干ORM框架,从而提供了ORM的对象关系工具,其中包括 JDO、Hibernate、iBatis和TopLink。所有这些都遵从Spring的通用事务和DAO异常层结构。 ? Spring DAO:JDBC DAO抽象层提供了有意义的异常层次的结构,可用该结构来管理异常处理和不同数据供应商抛出的异常错误信息。异常层次结构简化了错误处理,并且大大的降低了需要编写的异常代码数量(例如,打开和关系连接)。Spring DAO的面向JDBC的异常遵从通用的DAO异常层结构。 ? Spring WEB:Web上下文模块建立在上下文模块(Context)的基础之上,为基于Web服务的应用程序提供了上下文的服务。所以Spring 框架支持 Jakarta Struts的集成。Web模块还简化了处理多部分请求及将请求参数绑定到域对象的工作。 ? Spring上下文(Context):Spring上下文是一个配置文件,向Spring框架提供上下文信息。Spring上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化校验和调度功能。 ? Spring MVC:Spring的MVC框架是一个全功能的构建Web应用程序的MVC实现。通过策略接口,MVC框架变成为高度可配置的,MVC 容纳的大量视图技术,包括JSP、Velocity、Tiles、iText和Pol * 使用spring有什么好处? ◆Spring能有效地组织你的中间层对象,无论你是否选择使用了EJB。如果你仅仅使用了Struts或其他的包含了J2EE特有APIs的framework,你会发现Spring关注了遗留下的问题,。 ◆Spring能消除在许多工程上对Singleton的过多使用。根据我的经验,这是一个主要的问题,它减少了系统的可测试性和面向对象特性。 ◆Spring能消除使用各种各样格式的属性定制文件的需要,在整个应用和工程中,可通过一种一致的方法来进行配置。曾经感到迷惑,一个特定类要查找迷幻般的属性关键字或系统属性,为此不得不读Javadoc乃至源编码吗?有了Spring,你可很简单地看到类的JavaBean属性。倒置控制的使用(在下面讨论)帮助完成这种简化。 ◆Spring能通过接口而不是类促进好的编程习惯,减少编程代价到几乎为零。 ◆Spring被设计为让使用它创建的应用尽可能少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。 ◆使用Spring构建的应用程序易于单元测试。 ◆Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口,却不会影响调用代码。 ◆Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物,它们适于许多web应用。例如,Spring能使用AOP提供声明性事务而不通过使用EJB容器,如果你仅仅需要与单个的数据库打交道,甚至不需要JTA实现。 ■Spring为数据存取提供了一致的框架,不论是使用JDBC或O/R mapping产品(如Hibernate)。 Spring确实使你能通过最简单可行的解决办法解决你的问题。这些特性是有很大价值的。 总结起来,Spring有如下优点: ◆低侵入式设计,代码污染极低 ◆ 独立于各种应用服务器,可以真正实现Write Once,Run Anywhere的承诺

Webbuilder和Spring框架搭建

1.搭建好Spring环境或者Spring+Hibernate环境 2.下载Webbuilder使用源码搭建好Webbuilder环境 Webbuilder配置要点。 Tomcat的Context.xml中添加 对应的jar包也要有; 项目的Web.xml中配置

WebBuilder main contextConfigLocation classpath*:/applicationContext*.xml org.springframework.web.context.ContextLoaderListener WebBuilder Core Service main main https://www.360docs.net/doc/78100657.html,mon.Main 1 main /main

spring框架

spring框架 目录 编辑本段定义 要谈Spring的历史,就要先谈J2EE。J2EE应用程序的广泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核心中间层概念的标准化,但是在实践中并没有获得绝对的成功,因为开发效率,开发难度和实际的性能都令人失望。 曾经使用过EJB开发J2EE应用的人,一定知道,在EJB开始的学习和应用非常的艰苦,很多东西都不能一下子就很容易的理解。EJB要严格地继承各种不同类型的接口,类似的或者重复的代码大量存在。而配置也是复杂和单调,同样使用JNDI进行对象查找的代码也是单调而枯燥。虽然有一些开发工作随着xdoclet的出现,而有所缓解,但是学习EJB的高昂代价,和极低的开发效率,极高的资源消耗,都造成了EJB的使用困难。而Spring 出现的初衷就是为了解决类似的这些问题。 Spring的一个最大的目的就是使J2EE开发更加容易。同时,Spring 之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Old Java Object)对象提供企业级的服务。 Spring的形成,最初来自Rod Jahnson所著的一本很有影响力的书籍《Expert One-on-One J2EE Design and Development》,就是在这本书中第一次出现了Spring的一些核心思想,该书出版于2002年。另外一本书《Expert One-on-One J2EE Development without EJB》,更进一步阐述了在不使用EJB开发J2EE企业级应用的一些设计思想和具体的做法。有时间了可以详细的研读一下。 Spring的初衷: 1、J2EE开始应该更加简单。 2、使用接口而不是使用类,是更好的编程习惯。Spring将使用接口的复杂度几乎降低到了零。 3、为JavaBean提供了一个更好的应用配置框架。

相关主题
相关文档
最新文档